-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
Refactor Citations Relations Service Layer (#11189)
* Move logic from repository to service * Refactor repositories * Update tab configuration
1 parent
f603c78
commit 592d4d7
Showing
15 changed files
with
552 additions
and
371 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 9 additions & 15 deletions
24
src/main/java/org/jabref/logic/citation/repository/BibEntryRelationsRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,20 @@ | ||
package org.jabref.logic.citation.repository; | ||
|
||
import java.util.List; | ||
|
||
import org.jabref.model.entry.BibEntry; | ||
|
||
public interface BibEntryRelationsRepository { | ||
|
||
void insertCitations(BibEntry entry, List<BibEntry> citations); | ||
|
||
List<BibEntry> readCitations(BibEntry entry); | ||
|
||
boolean containsCitations(BibEntry entry); | ||
|
||
void insertReferences(BibEntry entry, List<BibEntry> citations); | ||
|
||
List<BibEntry> readReferences(BibEntry entry); | ||
|
||
/** | ||
* Fetch citations for a bib entry and update local database. | ||
* @param entry should not be null | ||
* @deprecated fetching citations should be done by the service layer (calling code) | ||
*/ | ||
@Deprecated | ||
void forceRefreshCitations(BibEntry entry); | ||
|
||
/** | ||
* Fetch references made by a bib entry and update local database. | ||
* @param entry should not be null | ||
* @deprecated fetching references should be done by the service layer (calling code) | ||
*/ | ||
@Deprecated | ||
void forceRefreshReferences(BibEntry entry); | ||
boolean containsReferences(BibEntry entry); | ||
} |
39 changes: 29 additions & 10 deletions
39
src/main/java/org/jabref/logic/citation/repository/LRUBibEntryRelationsCache.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,57 @@ | ||
package org.jabref.logic.citation.repository; | ||
|
||
import java.util.Collections; | ||
import java.util.LinkedHashSet; | ||
import java.util.List; | ||
import java.util.Map; | ||
import org.eclipse.jgit.util.LRUMap; | ||
import java.util.Set; | ||
|
||
import org.jabref.model.entry.BibEntry; | ||
import org.jabref.model.entry.identifier.DOI; | ||
|
||
import org.eclipse.jgit.util.LRUMap; | ||
|
||
public class LRUBibEntryRelationsCache { | ||
private static final Integer MAX_CACHED_ENTRIES = 100; | ||
private static final Map<String, List<BibEntry>> CITATIONS_MAP = new LRUMap<>(MAX_CACHED_ENTRIES, MAX_CACHED_ENTRIES); | ||
private static final Map<String, List<BibEntry>> REFERENCES_MAP = new LRUMap<>(MAX_CACHED_ENTRIES, MAX_CACHED_ENTRIES); | ||
private static final Map<DOI, Set<BibEntry>> CITATIONS_MAP = new LRUMap<>(MAX_CACHED_ENTRIES, MAX_CACHED_ENTRIES); | ||
private static final Map<DOI, Set<BibEntry>> REFERENCES_MAP = new LRUMap<>(MAX_CACHED_ENTRIES, MAX_CACHED_ENTRIES); | ||
|
||
public List<BibEntry> getCitations(BibEntry entry) { | ||
return CITATIONS_MAP.getOrDefault(entry.getDOI().map(DOI::getDOI).orElse(""), Collections.emptyList()); | ||
return entry | ||
.getDOI() | ||
.stream() | ||
.flatMap(doi -> CITATIONS_MAP.getOrDefault(doi, Set.of()).stream()) | ||
.toList(); | ||
} | ||
|
||
public List<BibEntry> getReferences(BibEntry entry) { | ||
return REFERENCES_MAP.getOrDefault(entry.getDOI().map(DOI::getDOI).orElse(""), Collections.emptyList()); | ||
return entry | ||
.getDOI() | ||
.stream() | ||
.flatMap(doi -> REFERENCES_MAP.getOrDefault(doi, Set.of()).stream()) | ||
.toList(); | ||
} | ||
|
||
public void cacheOrMergeCitations(BibEntry entry, List<BibEntry> citations) { | ||
entry.getDOI().ifPresent(doi -> CITATIONS_MAP.put(doi.getDOI(), citations)); | ||
entry.getDOI().ifPresent(doi -> { | ||
var cachedRelations = CITATIONS_MAP.getOrDefault(doi, new LinkedHashSet<>()); | ||
cachedRelations.addAll(citations); | ||
CITATIONS_MAP.put(doi, cachedRelations); | ||
}); | ||
} | ||
|
||
public void cacheOrMergeReferences(BibEntry entry, List<BibEntry> references) { | ||
entry.getDOI().ifPresent(doi -> REFERENCES_MAP.putIfAbsent(doi.getDOI(), references)); | ||
entry.getDOI().ifPresent(doi -> { | ||
var cachedRelations = REFERENCES_MAP.getOrDefault(doi, new LinkedHashSet<>()); | ||
cachedRelations.addAll(references); | ||
REFERENCES_MAP.put(doi, cachedRelations); | ||
}); | ||
} | ||
|
||
public boolean citationsCached(BibEntry entry) { | ||
return CITATIONS_MAP.containsKey(entry.getDOI().map(DOI::getDOI).orElse("")); | ||
return entry.getDOI().map(CITATIONS_MAP::containsKey).orElse(false); | ||
} | ||
|
||
public boolean referencesCached(BibEntry entry) { | ||
return REFERENCES_MAP.containsKey(entry.getDOI().map(DOI::getDOI).orElse("")); | ||
return entry.getDOI().map(REFERENCES_MAP::containsKey).orElse(false); | ||
} | ||
} |
69 changes: 20 additions & 49 deletions
69
src/main/java/org/jabref/logic/citation/repository/LRUBibEntryRelationsRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,49 @@ | ||
package org.jabref.logic.citation.repository; | ||
|
||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import org.jabref.logic.importer.fetcher.CitationFetcher; | ||
import org.jabref.logic.importer.FetcherException; | ||
import org.jabref.model.entry.BibEntry; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class LRUBibEntryRelationsRepository implements BibEntryRelationsRepository { | ||
private static final Logger LOGGER = LoggerFactory | ||
.getLogger(LRUBibEntryRelationsRepository.class); | ||
|
||
private final CitationFetcher fetcher; | ||
private final LRUBibEntryRelationsCache cache; | ||
|
||
public LRUBibEntryRelationsRepository(CitationFetcher fetcher, LRUBibEntryRelationsCache cache) { | ||
this.fetcher = fetcher; | ||
public LRUBibEntryRelationsRepository(LRUBibEntryRelationsCache cache) { | ||
this.cache = cache; | ||
} | ||
|
||
@Override | ||
public List<BibEntry> readCitations(BibEntry entry) { | ||
if (needToRefreshCitations(entry)) { | ||
forceRefreshCitations(entry); | ||
} | ||
|
||
return cache.getCitations(entry); | ||
public void insertCitations(BibEntry entry, List<BibEntry> citations) { | ||
cache.cacheOrMergeCitations( | ||
entry, Objects.requireNonNullElseGet(citations, List::of) | ||
); | ||
} | ||
|
||
@Override | ||
public List<BibEntry> readReferences(BibEntry entry) { | ||
if (needToRefreshReferences(entry)) { | ||
List<BibEntry> references; | ||
try { | ||
references = fetcher.searchCiting(entry); | ||
} catch (FetcherException e) { | ||
LOGGER.error("Error while fetching references", e); | ||
references = List.of(); | ||
} | ||
cache.cacheOrMergeReferences(entry, references); | ||
} | ||
|
||
return cache.getReferences(entry); | ||
public List<BibEntry> readCitations(BibEntry entry) { | ||
return cache.getCitations(entry); | ||
} | ||
|
||
@Override | ||
public void forceRefreshCitations(BibEntry entry) { | ||
try { | ||
List<BibEntry> citations = fetcher.searchCitedBy(entry); | ||
cache.cacheOrMergeCitations(entry, citations); | ||
} catch (FetcherException e) { | ||
LOGGER.error("Error while fetching citations", e); | ||
} | ||
public boolean containsCitations(BibEntry entry) { | ||
return cache.citationsCached(entry); | ||
} | ||
|
||
private boolean needToRefreshCitations(BibEntry entry) { | ||
return !cache.citationsCached(entry); | ||
@Override | ||
public void insertReferences(BibEntry entry, List<BibEntry> references) { | ||
cache.cacheOrMergeReferences( | ||
entry, Objects.requireNonNullElseGet(references, List::of) | ||
); | ||
} | ||
|
||
private boolean needToRefreshReferences(BibEntry entry) { | ||
return !cache.referencesCached(entry); | ||
@Override | ||
public List<BibEntry> readReferences(BibEntry entry) { | ||
return cache.getReferences(entry); | ||
} | ||
|
||
@Override | ||
public void forceRefreshReferences(BibEntry entry) { | ||
List<BibEntry> references; | ||
try { | ||
references = fetcher.searchCiting(entry); | ||
} catch (FetcherException e) { | ||
LOGGER.error("Error while fetching references", e); | ||
references = List.of(); | ||
} | ||
cache.cacheOrMergeReferences(entry, references); | ||
public boolean containsReferences(BibEntry entry) { | ||
return cache.referencesCached(entry); | ||
} | ||
} |
56 changes: 40 additions & 16 deletions
56
src/main/java/org/jabref/logic/citation/service/SearchCitationsRelationsService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,60 @@ | ||
package org.jabref.logic.citation.service; | ||
|
||
import java.util.List; | ||
|
||
import org.jabref.logic.citation.repository.BibEntryRelationsRepository; | ||
import org.jabref.logic.importer.fetcher.CitationFetcher; | ||
import org.jabref.model.entry.BibEntry; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class SearchCitationsRelationsService { | ||
|
||
BibEntryRelationsRepository relationsRepository; | ||
private static final Logger LOGGER = LoggerFactory | ||
.getLogger(SearchCitationsRelationsService.class); | ||
|
||
public SearchCitationsRelationsService(BibEntryRelationsRepository repository) { | ||
this.relationsRepository = repository; | ||
} | ||
private final CitationFetcher citationFetcher; | ||
private final BibEntryRelationsRepository relationsRepository; | ||
|
||
public List<BibEntry> searchReferences(BibEntry referencer) { | ||
return this.relationsRepository.readReferences(referencer); | ||
public SearchCitationsRelationsService( | ||
CitationFetcher citationFetcher, BibEntryRelationsRepository repository | ||
) { | ||
this.citationFetcher = citationFetcher; | ||
this.relationsRepository = repository; | ||
} | ||
|
||
public List<BibEntry> searchReferences(BibEntry referencer, boolean forceUpdate) { | ||
if (forceUpdate) { | ||
this.relationsRepository.forceRefreshReferences(referencer); | ||
if (forceUpdate || !this.relationsRepository.containsReferences(referencer)) { | ||
try { | ||
var references = this.citationFetcher.searchCiting(referencer); | ||
if (!references.isEmpty()) { | ||
this.relationsRepository.insertReferences(referencer, references); | ||
} | ||
} catch (Exception e) { | ||
var errMsg = "Error while fetching references for entry %s".formatted( | ||
referencer.getTitle() | ||
); | ||
LOGGER.error(errMsg); | ||
} | ||
} | ||
return this.searchReferences(referencer); | ||
} | ||
|
||
public List<BibEntry> searchCitations(BibEntry cited) { | ||
return this.relationsRepository.readCitations(cited); | ||
return this.relationsRepository.readReferences(referencer); | ||
} | ||
|
||
public List<BibEntry> searchCitations(BibEntry cited, boolean forceUpdate) { | ||
if (forceUpdate) { | ||
this.relationsRepository.forceRefreshCitations(cited); | ||
if (forceUpdate || !this.relationsRepository.containsCitations(cited)) { | ||
try { | ||
var citations = this.citationFetcher.searchCitedBy(cited); | ||
if (!citations.isEmpty()) { | ||
this.relationsRepository.insertCitations(cited, citations); | ||
} | ||
} catch (Exception e) { | ||
var errMsg = "Error while fetching citations for entry %s".formatted( | ||
cited.getTitle() | ||
); | ||
LOGGER.error(errMsg); | ||
} | ||
} | ||
return this.searchCitations(cited); | ||
return this.relationsRepository.readCitations(cited); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
.../java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryHelpersForTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package org.jabref.logic.citation.repository; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.BiConsumer; | ||
import java.util.function.Function; | ||
|
||
import org.jabref.model.entry.BibEntry; | ||
|
||
public class BibEntryRelationsRepositoryHelpersForTest { | ||
public static class Mocks { | ||
public static BibEntryRelationsRepository from( | ||
Function<BibEntry, List<BibEntry>> retrieveCitations, | ||
BiConsumer<BibEntry, List<BibEntry>> insertCitations, | ||
Function<BibEntry, List<BibEntry>> retrieveReferences, | ||
BiConsumer<BibEntry, List<BibEntry>> insertReferences | ||
) { | ||
return new BibEntryRelationsRepository() { | ||
@Override | ||
public void insertCitations(BibEntry entry, List<BibEntry> citations) { | ||
insertCitations.accept(entry, citations); | ||
} | ||
|
||
@Override | ||
public List<BibEntry> readCitations(BibEntry entry) { | ||
return retrieveCitations.apply(entry); | ||
} | ||
|
||
@Override | ||
public boolean containsCitations(BibEntry entry) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public void insertReferences(BibEntry entry, List<BibEntry> citations) { | ||
insertReferences.accept(entry, citations); | ||
} | ||
|
||
@Override | ||
public List<BibEntry> readReferences(BibEntry entry) { | ||
return retrieveReferences.apply(entry); | ||
} | ||
|
||
@Override | ||
public boolean containsReferences(BibEntry entry) { | ||
return true; | ||
} | ||
}; | ||
} | ||
|
||
public static BibEntryRelationsRepository from( | ||
Map<BibEntry, List<BibEntry>> citationsDB, Map<BibEntry, List<BibEntry>> referencesDB | ||
) { | ||
return new BibEntryRelationsRepository() { | ||
@Override | ||
public void insertCitations(BibEntry entry, List<BibEntry> citations) { | ||
citationsDB.put(entry, citations); | ||
} | ||
|
||
@Override | ||
public List<BibEntry> readCitations(BibEntry entry) { | ||
return citationsDB.getOrDefault(entry, List.of()); | ||
} | ||
|
||
@Override | ||
public boolean containsCitations(BibEntry entry) { | ||
return citationsDB.containsKey(entry); | ||
} | ||
|
||
@Override | ||
public void insertReferences(BibEntry entry, List<BibEntry> citations) { | ||
referencesDB.put(entry, citations); | ||
} | ||
|
||
@Override | ||
public List<BibEntry> readReferences(BibEntry entry) { | ||
return referencesDB.getOrDefault(entry, List.of()); | ||
} | ||
|
||
@Override | ||
public boolean containsReferences(BibEntry entry) { | ||
return referencesDB.containsKey(entry); | ||
} | ||
}; | ||
} | ||
} | ||
} |
128 changes: 0 additions & 128 deletions
128
src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTest.java
This file was deleted.
Oops, something went wrong.
39 changes: 0 additions & 39 deletions
39
...est/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java
This file was deleted.
Oops, something went wrong.
98 changes: 98 additions & 0 deletions
98
src/test/java/org/jabref/logic/citation/repository/LRUBibEntryRelationsRepositoryTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package org.jabref.logic.citation.repository; | ||
|
||
import java.util.List; | ||
import java.util.random.RandomGenerator; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
import java.util.stream.Stream; | ||
|
||
import org.jabref.model.entry.BibEntry; | ||
import org.jabref.model.entry.field.StandardField; | ||
|
||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertFalse; | ||
import static org.junit.jupiter.api.Assertions.assertNotSame; | ||
|
||
class LRUBibEntryRelationsRepositoryTest { | ||
|
||
private static Stream<BibEntry> createBibEntries() { | ||
return IntStream | ||
.range(0, 150) | ||
.mapToObj(LRUBibEntryRelationsRepositoryTest::createBibEntry); | ||
} | ||
|
||
private static BibEntry createBibEntry(int i) { | ||
return new BibEntry() | ||
.withCitationKey(String.valueOf(i)) | ||
.withField(StandardField.DOI, "10.1234/5678" + i); | ||
} | ||
|
||
private static List<BibEntry> createRelations(BibEntry entry) { | ||
return entry | ||
.getCitationKey() | ||
.map(key -> RandomGenerator | ||
.StreamableGenerator.of("L128X256MixRandom").ints(150) | ||
.mapToObj(i -> new BibEntry() | ||
.withCitationKey("%s relation %s".formatted(key, i)) | ||
.withField(StandardField.DOI, "10.2345/6789" + i) | ||
) | ||
) | ||
.orElseThrow() | ||
.toList(); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("createBibEntries") | ||
void repositoryShouldMergeCitationsWhenInserting(BibEntry bibEntry) { | ||
// GIVEN | ||
var bibEntryRelationsRepository = new LRUBibEntryRelationsRepository( | ||
new LRUBibEntryRelationsCache() | ||
); | ||
assertFalse(bibEntryRelationsRepository.containsCitations(bibEntry)); | ||
|
||
// WHEN | ||
var firstRelations = createRelations(bibEntry); | ||
var secondRelations = createRelations(bibEntry); | ||
bibEntryRelationsRepository.insertCitations(bibEntry, firstRelations); | ||
bibEntryRelationsRepository.insertCitations(bibEntry, secondRelations); | ||
|
||
// THEN | ||
var uniqueRelations = Stream | ||
.concat(firstRelations.stream(), secondRelations.stream()) | ||
.distinct() | ||
.toList(); | ||
var relationFromCache = bibEntryRelationsRepository.readCitations(bibEntry); | ||
assertFalse(uniqueRelations.isEmpty()); | ||
assertNotSame(uniqueRelations, relationFromCache); | ||
assertEquals(uniqueRelations, relationFromCache); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("createBibEntries") | ||
void repositoryShouldMergeReferencesWhenInserting(BibEntry bibEntry) { | ||
// GIVEN | ||
var bibEntryRelationsRepository = new LRUBibEntryRelationsRepository( | ||
new LRUBibEntryRelationsCache() | ||
); | ||
assertFalse(bibEntryRelationsRepository.containsReferences(bibEntry)); | ||
|
||
// WHEN | ||
var firstRelations = createRelations(bibEntry); | ||
var secondRelations = createRelations(bibEntry); | ||
bibEntryRelationsRepository.insertReferences(bibEntry, firstRelations); | ||
bibEntryRelationsRepository.insertReferences(bibEntry, secondRelations); | ||
|
||
// THEN | ||
var uniqueRelations = Stream | ||
.concat(firstRelations.stream(), secondRelations.stream()) | ||
.distinct() | ||
.collect(Collectors.toList()); | ||
var relationFromCache = bibEntryRelationsRepository.readReferences(bibEntry); | ||
assertFalse(uniqueRelations.isEmpty()); | ||
assertNotSame(uniqueRelations, relationFromCache); | ||
assertEquals(uniqueRelations, relationFromCache); | ||
} | ||
} |
239 changes: 164 additions & 75 deletions
239
src/test/java/org/jabref/logic/citation/service/SearchCitationsRelationsServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,178 @@ | ||
package org.jabref.logic.citation.service; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import org.jabref.logic.citation.repository.BibEntryRelationsRepositoryTestHelpers; | ||
|
||
import org.jabref.logic.citation.repository.BibEntryRelationsRepositoryHelpersForTest; | ||
import org.jabref.logic.importer.fetcher.CitationFetcherHelpersForTest; | ||
import org.jabref.model.entry.BibEntry; | ||
import org.junit.jupiter.api.Assertions; | ||
|
||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
class SearchCitationsRelationsServiceTest { | ||
|
||
@Test | ||
void serviceShouldSearchForReferences() { | ||
// GIVEN | ||
var referencesToReturn = List.of(new BibEntry()); | ||
var repository = BibEntryRelationsRepositoryTestHelpers.CreateRepository.from( | ||
List::of, e -> referencesToReturn, e -> {}, e -> {} | ||
); | ||
var searchCitationsRelationsService = new SearchCitationsRelationsService(repository); | ||
|
||
// WHEN | ||
var referencer = new BibEntry(); | ||
List<BibEntry> references = searchCitationsRelationsService.searchReferences(referencer); | ||
|
||
// THEN | ||
Assertions.assertEquals(referencesToReturn, references); | ||
} | ||
@Nested | ||
class CitationsTests { | ||
@Test | ||
void serviceShouldSearchForCitations() { | ||
// GIVEN | ||
var cited = new BibEntry(); | ||
var citationsToReturn = List.of(new BibEntry()); | ||
var repository = BibEntryRelationsRepositoryHelpersForTest.Mocks.from( | ||
e -> citationsToReturn, null, null, null | ||
); | ||
var searchService = new SearchCitationsRelationsService(null, repository); | ||
|
||
@Test | ||
void serviceShouldForceReferencesUpdate() { | ||
// GiVEN | ||
var newReference = new BibEntry(); | ||
var referencesToReturn = List.of(newReference); | ||
var referenceToUpdate = new ArrayList<BibEntry>(); | ||
var repository = BibEntryRelationsRepositoryTestHelpers.CreateRepository.from( | ||
List::of, e -> referencesToReturn, e -> {}, e -> referenceToUpdate.add(newReference) | ||
); | ||
var searchCitationsRelationsService = new SearchCitationsRelationsService(repository); | ||
|
||
// WHEN | ||
var referencer = new BibEntry(); | ||
var references = searchCitationsRelationsService.searchReferences(referencer, true); | ||
|
||
// THEN | ||
Assertions.assertEquals(referencesToReturn, references); | ||
Assertions.assertEquals(1, referenceToUpdate.size()); | ||
Assertions.assertSame(newReference, referenceToUpdate.getFirst()); | ||
Assertions.assertNotSame(referencesToReturn, referenceToUpdate); | ||
} | ||
// WHEN | ||
List<BibEntry> citations = searchService.searchCitations(cited, false); | ||
|
||
// THEN | ||
assertEquals(citationsToReturn, citations); | ||
} | ||
|
||
@Test | ||
void serviceShouldForceCitationsUpdate() { | ||
// GiVEN | ||
var cited = new BibEntry(); | ||
var newCitations = new BibEntry(); | ||
var citationsToReturn = List.of(newCitations); | ||
var citationsDatabase = new HashMap<BibEntry, List<BibEntry>>(); | ||
var fetcher = CitationFetcherHelpersForTest.Mocks.from( | ||
entry -> { | ||
if (entry == cited) { | ||
return citationsToReturn; | ||
} | ||
return List.of(); | ||
}, | ||
null | ||
); | ||
var repository = BibEntryRelationsRepositoryHelpersForTest.Mocks.from( | ||
e -> citationsToReturn, | ||
citationsDatabase::put, | ||
List::of, | ||
(e, r) -> { } | ||
); | ||
var searchService = new SearchCitationsRelationsService(fetcher, repository); | ||
|
||
// WHEN | ||
var citations = searchService.searchCitations(cited, true); | ||
|
||
// THEN | ||
assertTrue(citationsDatabase.containsKey(cited)); | ||
assertEquals(citationsToReturn, citationsDatabase.get(cited)); | ||
assertEquals(citationsToReturn, citations); | ||
} | ||
|
||
@Test | ||
void serviceShouldFetchCitationsIfRepositoryIsEmpty() { | ||
var cited = new BibEntry(); | ||
var newCitations = new BibEntry(); | ||
var citationsToReturn = List.of(newCitations); | ||
var citationsDatabase = new HashMap<BibEntry, List<BibEntry>>(); | ||
var fetcher = CitationFetcherHelpersForTest.Mocks.from( | ||
entry -> { | ||
if (entry == cited) { | ||
return citationsToReturn; | ||
} | ||
return List.of(); | ||
}, | ||
null | ||
); | ||
var repository = BibEntryRelationsRepositoryHelpersForTest.Mocks.from( | ||
citationsDatabase, null | ||
); | ||
var searchService = new SearchCitationsRelationsService(fetcher, repository); | ||
|
||
@Test | ||
void serviceShouldSearchForCitations() { | ||
// GIVEN | ||
var citationsToReturn = List.of(new BibEntry()); | ||
var repository = BibEntryRelationsRepositoryTestHelpers.CreateRepository.from( | ||
e -> citationsToReturn, List::of, e -> {}, e -> {} | ||
); | ||
var searchCitationsRelationsService = new SearchCitationsRelationsService(repository); | ||
|
||
// WHEN | ||
var cited = new BibEntry(); | ||
List<BibEntry> citations = searchCitationsRelationsService.searchCitations(cited); | ||
|
||
// THEN | ||
Assertions.assertEquals(citationsToReturn, citations); | ||
// WHEN | ||
var citations = searchService.searchCitations(cited, false); | ||
|
||
// THEN | ||
assertTrue(citationsDatabase.containsKey(cited)); | ||
assertEquals(citationsToReturn, citationsDatabase.get(cited)); | ||
assertEquals(citationsToReturn, citations); | ||
} | ||
} | ||
|
||
@Test | ||
void serviceShouldForceCitationsUpdate() { | ||
// GiVEN | ||
var newCitations = new BibEntry(); | ||
var citationsToReturn = List.of(newCitations); | ||
var citationsToUpdate = new ArrayList<BibEntry>(); | ||
var repository = BibEntryRelationsRepositoryTestHelpers.CreateRepository.from( | ||
e -> citationsToReturn, List::of, e -> citationsToUpdate.add(newCitations), e -> {} | ||
); | ||
var searchCitationsRelationsService = new SearchCitationsRelationsService(repository); | ||
|
||
// WHEN | ||
var cited = new BibEntry(); | ||
var citations = searchCitationsRelationsService.searchCitations(cited, true); | ||
|
||
// THEN | ||
Assertions.assertEquals(citationsToReturn, citations); | ||
Assertions.assertEquals(1, citationsToUpdate.size()); | ||
Assertions.assertSame(newCitations, citationsToUpdate.getFirst()); | ||
Assertions.assertNotSame(citationsToReturn, citationsToUpdate); | ||
@Nested | ||
class ReferencesTests { | ||
@Test | ||
void serviceShouldSearchForReferences() { | ||
// GIVEN | ||
var referencer = new BibEntry(); | ||
var referencesToReturn = List.of(new BibEntry()); | ||
var repository = BibEntryRelationsRepositoryHelpersForTest.Mocks.from( | ||
null, null, e -> referencesToReturn, null | ||
); | ||
var searchService = new SearchCitationsRelationsService(null, repository); | ||
|
||
// WHEN | ||
List<BibEntry> references = searchService.searchReferences(referencer, false); | ||
|
||
// THEN | ||
assertEquals(referencesToReturn, references); | ||
} | ||
|
||
@Test | ||
void serviceShouldCallTheFetcherForReferencesIWhenForceUpdateIsTrue() { | ||
// GIVEN | ||
var referencer = new BibEntry(); | ||
var newReference = new BibEntry(); | ||
var referencesToReturn = List.of(newReference); | ||
var referencesDatabase = new HashMap<BibEntry, List<BibEntry>>(); | ||
var fetcher = CitationFetcherHelpersForTest.Mocks.from(null, entry -> { | ||
if (entry == referencer) { | ||
return referencesToReturn; | ||
} | ||
return List.of(); | ||
}); | ||
var repository = BibEntryRelationsRepositoryHelpersForTest.Mocks.from( | ||
List::of, | ||
(e, c) -> { }, | ||
e -> referencesToReturn, | ||
referencesDatabase::put | ||
); | ||
var searchService = new SearchCitationsRelationsService(fetcher, repository); | ||
|
||
// WHEN | ||
var references = searchService.searchReferences(referencer, true); | ||
|
||
// THEN | ||
assertTrue(referencesDatabase.containsKey(referencer)); | ||
assertEquals(referencesToReturn, referencesDatabase.get(referencer)); | ||
assertEquals(referencesToReturn, references); | ||
} | ||
|
||
@Test | ||
void serviceShouldFetchReferencesIfRepositoryIsEmpty() { | ||
var reference = new BibEntry(); | ||
var newCitations = new BibEntry(); | ||
var referencesToReturn = List.of(newCitations); | ||
var referencesDatabase = new HashMap<BibEntry, List<BibEntry>>(); | ||
var fetcher = CitationFetcherHelpersForTest.Mocks.from( | ||
null, | ||
entry -> { | ||
if (entry == reference) { | ||
return referencesToReturn; | ||
} | ||
return List.of(); | ||
} | ||
); | ||
var repository = BibEntryRelationsRepositoryHelpersForTest.Mocks.from( | ||
null, referencesDatabase | ||
); | ||
var searchService = new SearchCitationsRelationsService(fetcher, repository); | ||
|
||
// WHEN | ||
var references = searchService.searchReferences(reference, false); | ||
|
||
// THEN | ||
assertTrue(referencesDatabase.containsKey(reference)); | ||
assertEquals(referencesToReturn, referencesDatabase.get(reference)); | ||
assertEquals(referencesToReturn, references); | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/test/java/org/jabref/logic/importer/fetcher/CitationFetcherHelpersForTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package org.jabref.logic.importer.fetcher; | ||
|
||
import java.util.List; | ||
import java.util.function.Function; | ||
|
||
import org.jabref.model.entry.BibEntry; | ||
|
||
public class CitationFetcherHelpersForTest { | ||
public static class Mocks { | ||
public static CitationFetcher from( | ||
Function<BibEntry, List<BibEntry>> retrieveCitedBy, | ||
Function<BibEntry, List<BibEntry>> retrieveCiting | ||
) { | ||
return new CitationFetcher() { | ||
@Override | ||
public List<BibEntry> searchCitedBy(BibEntry entry) { | ||
return retrieveCitedBy.apply(entry); | ||
} | ||
|
||
@Override | ||
public List<BibEntry> searchCiting(BibEntry entry) { | ||
return retrieveCiting.apply(entry); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "Test citation fetcher"; | ||
} | ||
}; | ||
} | ||
} | ||
} |