Skip to content

Commit

Permalink
Feature/add abstract field to complex search (#7079)
Browse files Browse the repository at this point in the history
  • Loading branch information
DominikVoigt authored Nov 7, 2020
1 parent 4709535 commit df80c13
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public WebSearchPaneViewModel(ImportFormatPreferences importPreferences, JabRefF
preferences.putInt(JabRefPreferences.SELECTED_FETCHER_INDEX, newIndex);
});

String allowedFields = "((author|journal|title|year|year-range):\\s?)?";
String allowedFields = "((author|abstract|journal|title|year|year-range):\\s?)?";
// Either a single word, or a phrase with quotes, or a year-range
String allowedTermText = "(((\\d{4}-\\d{4})|(\\w+)|(\"\\w+[^\"]*\"))\\s?)+";
queryPattern = Pattern.compile("^(" + allowedFields + allowedTermText + ")+$");
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ public List<BibEntry> performComplexSearch(ComplexSearchQuery complexSearchQuery
List<String> searchTerms = new ArrayList<>();
complexSearchQuery.getAuthors().forEach(author -> searchTerms.add("au:" + author));
complexSearchQuery.getTitlePhrases().forEach(title -> searchTerms.add("ti:" + title));
complexSearchQuery.getTitlePhrases().forEach(abstr -> searchTerms.add("abs:" + abstr));
complexSearchQuery.getJournal().ifPresent(journal -> searchTerms.add("jr:" + journal));
// Since ArXiv API does not support year search, we ignore the year related terms
complexSearchQuery.getToYear().ifPresent(year -> searchTerms.add(year.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.StringJoiner;

import org.jabref.model.strings.StringUtil;

Expand All @@ -15,15 +16,17 @@ public class ComplexSearchQuery {
private final List<String> defaultField;
private final List<String> authors;
private final List<String> titlePhrases;
private final List<String> abstractPhrases;
private final Integer fromYear;
private final Integer toYear;
private final Integer singleYear;
private final String journal;

private ComplexSearchQuery(List<String> defaultField, List<String> authors, List<String> titlePhrases, Integer fromYear, Integer toYear, Integer singleYear, String journal) {
private ComplexSearchQuery(List<String> defaultField, List<String> authors, List<String> titlePhrases, List<String> abstractPhrases, Integer fromYear, Integer toYear, Integer singleYear, String journal) {
this.defaultField = defaultField;
this.authors = authors;
this.titlePhrases = titlePhrases;
this.abstractPhrases = abstractPhrases;
this.fromYear = fromYear;
// Some APIs do not support, or not fully support, year based search. In these cases, the non applicable parameters are ignored.
this.toYear = toYear;
Expand All @@ -38,6 +41,7 @@ public static ComplexSearchQuery fromTerms(Collection<Term> terms) {
switch (term.field().toLowerCase()) {
case "author" -> builder.author(termText);
case "title" -> builder.titlePhrase(termText);
case "abstract" -> builder.abstractPhrase(termText);
case "journal" -> builder.journal(termText);
case "year" -> builder.singleYear(Integer.valueOf(termText));
case "year-range" -> builder.parseYearRange(termText);
Expand All @@ -60,6 +64,10 @@ public List<String> getTitlePhrases() {
return titlePhrases;
}

public List<String> getAbstractPhrases() {
return abstractPhrases;
}

public Optional<Integer> getFromYear() {
return Optional.ofNullable(fromYear);
}
Expand Down Expand Up @@ -101,6 +109,9 @@ public boolean equals(Object o) {
if (!(getTitlePhrases().containsAll(that.getTitlePhrases()) && that.getTitlePhrases().containsAll(getTitlePhrases()))) {
return false;
}
if (!(getAbstractPhrases().containsAll(that.getAbstractPhrases()) && that.getAbstractPhrases().containsAll(getAbstractPhrases()))) {
return false;
}
if (getFromYear().isPresent() ? !getFromYear().equals(that.getFromYear()) : that.getFromYear().isPresent()) {
return false;
}
Expand All @@ -115,33 +126,30 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
int result = defaultField != null ? defaultField.hashCode() : 0;
result = 31 * result + (getAuthors() != null ? getAuthors().hashCode() : 0);
result = 31 * result + (getTitlePhrases() != null ? getTitlePhrases().hashCode() : 0);
result = 31 * result + (getFromYear().isPresent() ? getFromYear().hashCode() : 0);
result = 31 * result + (getToYear().isPresent() ? getToYear().hashCode() : 0);
result = 31 * result + (getSingleYear().isPresent() ? getSingleYear().hashCode() : 0);
result = 31 * result + (getJournal().isPresent() ? getJournal().hashCode() : 0);
return result;
return Objects.hash(defaultField, getAuthors(), getSingleYear(), getAbstractPhrases(), getFromYear(), getToYear(), getTitlePhrases(), getJournal());
}

@Override
public String toString() {
StringBuilder stringRepresentation = new StringBuilder();
getSingleYear().ifPresent(singleYear -> stringRepresentation.append(singleYear).append(" "));
getFromYear().ifPresent(fromYear -> stringRepresentation.append(fromYear).append(" "));
getToYear().ifPresent(toYear -> stringRepresentation.append(toYear).append(" "));
getJournal().ifPresent(journal -> stringRepresentation.append(journal).append(" "));
stringRepresentation.append(String.join(" ", getTitlePhrases()))
.append(String.join(" ", getDefaultFieldPhrases()))
.append(String.join(" ", getAuthors()));
return stringRepresentation.toString();
StringJoiner stringJoiner = new StringJoiner(" ");

getSingleYear().ifPresent(singleYear -> stringJoiner.add(singleYear.toString()));
getFromYear().ifPresent(fromYear -> stringJoiner.add(fromYear.toString()));
getToYear().ifPresent(toYear -> stringJoiner.add(toYear.toString()));
getJournal().ifPresent(stringJoiner::add);
stringJoiner.add(String.join(" ", getTitlePhrases()))
.add(String.join(" ", getDefaultFieldPhrases()))
.add(String.join(" ", getAuthors()))
.add(String.join(" ", getAbstractPhrases()));

return stringJoiner.toString();
}

public static class ComplexSearchQueryBuilder {
private List<String> defaultFieldPhrases = new ArrayList<>();
private List<String> authors = new ArrayList<>();
private List<String> titlePhrases = new ArrayList<>();
private List<String> abstractPhrases = new ArrayList<>();
private String journal;
private Integer fromYear;
private Integer toYear;
Expand Down Expand Up @@ -183,6 +191,18 @@ public ComplexSearchQueryBuilder titlePhrase(String titlePhrase) {
return this;
}

/**
* Adds abstract phrase and wraps it in quotes
*/
public ComplexSearchQueryBuilder abstractPhrase(String abstractPhrase) {
if (Objects.requireNonNull(abstractPhrase).isBlank()) {
throw new IllegalArgumentException("Parameter must not be blank");
}
// Strip all quotes before wrapping
this.titlePhrases.add(String.format("\"%s\"", abstractPhrase.replace("\"", "")));
return this;
}

public ComplexSearchQueryBuilder fromYearAndToYear(Integer fromYear, Integer toYear) {
if (Objects.nonNull(singleYear)) {
throw new IllegalArgumentException("You can not use single year and year range search.");
Expand Down Expand Up @@ -214,6 +234,7 @@ public ComplexSearchQueryBuilder terms(Collection<Term> terms) {
switch (term.field().toLowerCase()) {
case "author" -> this.author(termText);
case "title" -> this.titlePhrase(termText);
case "abstract" -> this.abstractPhrase(termText);
case "journal" -> this.journal(termText);
case "year" -> this.singleYear(Integer.valueOf(termText));
case "year-range" -> this.parseYearRange(termText);
Expand All @@ -235,7 +256,7 @@ public ComplexSearchQuery build() throws IllegalStateException {
if (textSearchFieldsAndYearFieldsAreEmpty()) {
throw new IllegalStateException("At least one text field has to be set");
}
return new ComplexSearchQuery(defaultFieldPhrases, authors, titlePhrases, fromYear, toYear, singleYear, journal);
return new ComplexSearchQuery(defaultFieldPhrases, authors, titlePhrases, abstractPhrases, fromYear, toYear, singleYear, journal);
}

void parseYearRange(String termText) {
Expand All @@ -259,7 +280,7 @@ void parseYearRange(String termText) {

private boolean textSearchFieldsAndYearFieldsAreEmpty() {
return this.stringListIsBlank(defaultFieldPhrases) && this.stringListIsBlank(titlePhrases) &&
this.stringListIsBlank(authors) && StringUtil.isBlank(journal) && yearFieldsAreEmpty();
this.stringListIsBlank(authors) && this.stringListIsBlank(abstractPhrases) && StringUtil.isBlank(journal) && yearFieldsAreEmpty();
}

private boolean yearFieldsAreEmpty() {
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/org/jabref/logic/importer/fetcher/IEEE.java
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,10 @@ public URL getComplexQueryURL(ComplexSearchQuery complexSearchQuery) throws URIS
if (!complexSearchQuery.getAuthors().isEmpty()) {
uriBuilder.addParameter("author", String.join(" AND ", complexSearchQuery.getAuthors()));
}
if (!complexSearchQuery.getAuthors().isEmpty()) {
if (!complexSearchQuery.getAbstractPhrases().isEmpty()) {
uriBuilder.addParameter("abstract", String.join(" AND ", complexSearchQuery.getAbstractPhrases()));
}
if (!complexSearchQuery.getTitlePhrases().isEmpty()) {
uriBuilder.addParameter("article_title", String.join(" AND ", complexSearchQuery.getTitlePhrases()));
}
complexSearchQuery.getJournal().ifPresent(journalTitle -> uriBuilder.addParameter("publication_title", journalTitle));
Expand Down

0 comments on commit df80c13

Please sign in to comment.