From 563b8ff59e23eb8ab3776e8057908f6e6fbb5ab3 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 15 Jul 2025 22:45:27 +0200 Subject: [PATCH 1/3] Show fetch exception at citation relation --- CHANGELOG.md | 1 + .../groupchange/GroupChangeDetailsView.java | 2 +- .../CitationRelationsTab.java | 82 +++++++++++-------- jablib/build.gradle.kts | 2 + jablib/src/main/java/module-info.java | 1 + .../SearchCitationsRelationsService.java | 37 ++++----- .../SemanticScholarCitationFetcher.java | 30 ++++++- .../main/resources/l10n/JabRef_en.properties | 10 ++- .../SearchCitationsRelationsServiceTest.java | 33 ++++---- versions/build.gradle.kts | 1 + 10 files changed, 117 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67855ca84f8..25a6c445031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We added the field `monthfiled` to the default list of fields to resolve BibTeX-Strings for [#13375](https://github.com/JabRef/jabref/issues/13375) - We added a new ID based fetcher for [EuropePMC](https://europepmc.org/). [#13389](https://github.com/JabRef/jabref/pull/13389) - We added an initial [cite as you write](https://retorque.re/zotero-better-bibtex/citing/cayw/) endpoint. [#13187](https://github.com/JabRef/jabref/issues/13187) +- In case no citation relation information can be fetched, we show the data providers reason. ### Changed diff --git a/jabgui/src/main/java/org/jabref/gui/collab/groupchange/GroupChangeDetailsView.java b/jabgui/src/main/java/org/jabref/gui/collab/groupchange/GroupChangeDetailsView.java index de428484f29..f29b929ad43 100644 --- a/jabgui/src/main/java/org/jabref/gui/collab/groupchange/GroupChangeDetailsView.java +++ b/jabgui/src/main/java/org/jabref/gui/collab/groupchange/GroupChangeDetailsView.java @@ -8,7 +8,7 @@ public final class GroupChangeDetailsView extends DatabaseChangeDetailsView { public GroupChangeDetailsView(GroupChange groupChange) { - String labelValue = ""; + String labelValue; if (groupChange.getGroupDiff().getNewGroupRoot() == null) { labelValue = groupChange.getName() + '.'; } else { diff --git a/jabgui/src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java b/jabgui/src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java index b883672d884..921cb476e06 100644 --- a/jabgui/src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java +++ b/jabgui/src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java @@ -201,22 +201,22 @@ private SplitPane getPaneAndStartSearch(BibEntry entry) { refreshCitingButton.setOnMouseClicked(_ -> { searchForRelations( - entry, - citingListView, + entry, + citingListView, abortCitingButton, - refreshCitingButton, - CitationFetcher.SearchType.CITES, - importCitingButton, + refreshCitingButton, + CitationFetcher.SearchType.CITES, + importCitingButton, citingProgress); }); refreshCitedByButton.setOnMouseClicked(_ -> searchForRelations( - entry, - citedByListView, + entry, + citedByListView, abortCitedButton, - refreshCitedByButton, - CitationFetcher.SearchType.CITED_BY, - importCitedByButton, + refreshCitedByButton, + CitationFetcher.SearchType.CITED_BY, + importCitedByButton, citedByProgress)); // Create SplitPane to hold all nodes above @@ -225,21 +225,21 @@ private SplitPane getPaneAndStartSearch(BibEntry entry) { styleFetchedListView(citingListView); searchForRelations( - entry, - citingListView, - abortCitingButton, + entry, + citingListView, + abortCitingButton, refreshCitingButton, - CitationFetcher.SearchType.CITES, - importCitingButton, + CitationFetcher.SearchType.CITES, + importCitingButton, citingProgress); searchForRelations( - entry, - citedByListView, - abortCitedButton, + entry, + citedByListView, + abortCitedButton, refreshCitedByButton, - CitationFetcher.SearchType.CITED_BY, - importCitedByButton, + CitationFetcher.SearchType.CITED_BY, + importCitedByButton, citedByProgress); return container; @@ -444,14 +444,13 @@ private void searchForRelations(BibEntry entry, CheckListView observableList = FXCollections.observableArrayList(); - - listView.setItems(observableList); + ObservableList resultList = FXCollections.observableArrayList(); + listView.setItems(resultList); // TODO: It should not be possible to cancel a search task that is already running for same tab - if (citingTask != null && !citingTask.isCancelled() && searchType == CitationFetcher.SearchType.CITES) { + if (searchType == CitationFetcher.SearchType.CITES && citingTask != null && !citingTask.isCancelled()) { citingTask.cancel(); - } else if (citedByTask != null && !citedByTask.isCancelled() && searchType == CitationFetcher.SearchType.CITED_BY) { + } else if (searchType == CitationFetcher.SearchType.CITED_BY && citedByTask != null && !citedByTask.isCancelled()) { citedByTask.cancel(); } @@ -468,13 +467,22 @@ private void searchForRelations(BibEntry entry, CheckListView { - LOGGER.error("Error while fetching citing Articles", exception); + LOGGER.error("Error while fetching {} papers", + searchType == CitationFetcher.SearchType.CITES ? "cited" : "citing", + exception); hideNodes(abortButton, progress, importButton); - listView.setPlaceholder(new Label(Localization.lang("Error while fetching citing entries: %0", - exception.getMessage()))); + String labelText; + if (searchType == CitationFetcher.SearchType.CITES) { + labelText = Localization.lang("Error while fetching cited entries: %0", exception.getMessage()); + } else { + labelText = Localization.lang("Error while fetching citing entries: %0", exception.getMessage()); + } + Label placeholder = new Label(labelText); + placeholder.setWrapText(true); + listView.setPlaceholder(placeholder); refreshButton.setVisible(true); dialogService.notify(exception.getMessage()); }) @@ -490,13 +498,13 @@ private BackgroundTask> createBackgroundTask( return switch (searchType) { case CitationFetcher.SearchType.CITES -> { citingTask = BackgroundTask.wrap( - () -> this.searchCitationsRelationsService.searchReferences(entry) + () -> this.searchCitationsRelationsService.searchCites(entry) ); yield citingTask; } case CitationFetcher.SearchType.CITED_BY -> { citedByTask = BackgroundTask.wrap( - () -> this.searchCitationsRelationsService.searchCitations(entry) + () -> this.searchCitationsRelationsService.searchCitedBy(entry) ); yield citedByTask; } @@ -510,6 +518,8 @@ private void onSearchForRelationsSucceed(BibEntry entry, CheckListView observableList) { hideNodes(abortButton, progress); + // TODO: This could be a wrong database, because the user might have switched to another library + // If we were on fixing this, we would need to a) associate a BibEntry with a dababase or b) pass the database at "bindToEntry" BibDatabase database = stateManager.getActiveDatabase().map(BibDatabaseContext::getDatabase) .orElse(new BibDatabase()); observableList.setAll( @@ -523,15 +533,15 @@ private void onSearchForRelationsSucceed(BibEntry entry, CheckListView importEntries(listView.getCheckModel().getCheckedItems(), searchType, entry)); + importButton.setOnMouseClicked(_ -> importEntries(listView.getCheckModel().getCheckedItems(), searchType, entry)); showNodes(refreshButton, importButton); } @@ -540,7 +550,7 @@ private void prepareToSearchForRelations(Button abortButton, Button refreshButto showNodes(abortButton, progress); hideNodes(refreshButton, importButton); - abortButton.setOnAction(event -> { + abortButton.setOnAction(_ -> { hideNodes(abortButton, progress, importButton); showNodes(refreshButton); task.cancel(); diff --git a/jablib/build.gradle.kts b/jablib/build.gradle.kts index 998df49b311..14751c3c18f 100644 --- a/jablib/build.gradle.kts +++ b/jablib/build.gradle.kts @@ -106,6 +106,8 @@ dependencies { implementation("com.fasterxml:aalto-xml") + implementation("org.hisp.dhis:json-tree") + implementation("org.postgresql:postgresql") antlr("org.antlr:antlr4") diff --git a/jablib/src/main/java/module-info.java b/jablib/src/main/java/module-info.java index 07bd3b6884e..1eb2fc7079c 100644 --- a/jablib/src/main/java/module-info.java +++ b/jablib/src/main/java/module-info.java @@ -145,6 +145,7 @@ requires com.fasterxml.jackson.databind; requires com.fasterxml.jackson.dataformat.yaml; requires com.fasterxml.jackson.datatype.jsr310; + requires org.hisp.dhis.jsontree; // endregion // region HTTP clients diff --git a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java index 95db8900c1b..69ba4270496 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -39,29 +39,23 @@ public SearchCitationsRelationsService(ImporterPreferences importerPreferences, ); } - /** - * @implNote Typically, this would be a Shim in JavaFX - */ @VisibleForTesting - public SearchCitationsRelationsService(CitationFetcher citationFetcher, + SearchCitationsRelationsService(CitationFetcher citationFetcher, BibEntryCitationsAndReferencesRepository repository ) { this.citationFetcher = citationFetcher; this.relationsRepository = repository; } - public List searchReferences(BibEntry referenced) { - boolean isFetchingAllowed = relationsRepository.isReferencesUpdatable(referenced) - || !relationsRepository.containsReferences(referenced); + public List searchCites(BibEntry referencing) throws FetcherException { + boolean isFetchingAllowed = + !relationsRepository.containsReferences(referencing) || + relationsRepository.isReferencesUpdatable(referencing); if (isFetchingAllowed) { - try { - List referencedBy = citationFetcher.searchCiting(referenced); - relationsRepository.insertReferences(referenced, referencedBy); - } catch (FetcherException e) { - LOGGER.error("Error while fetching references for entry {}", referenced.getTitle(), e); - } + List referencedBy = citationFetcher.searchCiting(referencing); + relationsRepository.insertReferences(referencing, referencedBy); } - return relationsRepository.readReferences(referenced); + return relationsRepository.readReferences(referencing); } /** @@ -69,16 +63,13 @@ public List searchReferences(BibEntry referenced) { * If the store was not empty and nothing was fetched after a successful fetch => the store will be erased and the returned collection will be empty * If the store was not empty and an error occurs while fetching => will return the content of the store */ - public List searchCitations(BibEntry cited) { - boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(cited) - || !relationsRepository.containsCitations(cited); + public List searchCitedBy(BibEntry cited) throws FetcherException { + boolean isFetchingAllowed = + !relationsRepository.containsCitations(cited) || + relationsRepository.isCitationsUpdatable(cited); if (isFetchingAllowed) { - try { - List citedBy = citationFetcher.searchCitedBy(cited); - relationsRepository.insertCitations(cited, citedBy); - } catch (FetcherException e) { - LOGGER.error("Error while fetching citations for entry {}", cited.getTitle(), e); - } + List citedBy = citationFetcher.searchCitedBy(cited); + relationsRepository.insertCitations(cited, citedBy); } return relationsRepository.readCitations(cited); } diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcher.java index 646ae02952c..5ca513c9f42 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcher.java @@ -8,15 +8,23 @@ import org.jabref.logic.importer.ImporterPreferences; import org.jabref.logic.importer.fetcher.CustomizableKeyFetcher; import org.jabref.logic.importer.fetcher.citation.CitationFetcher; +import org.jabref.logic.l10n.Localization; import org.jabref.logic.net.URLDownload; import org.jabref.logic.util.URLUtil; import org.jabref.model.entry.BibEntry; import com.google.gson.Gson; +import org.hisp.dhis.jsontree.JsonMixed; +import org.hisp.dhis.jsontree.JsonNode; import org.jspecify.annotations.NonNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SemanticScholarCitationFetcher implements CitationFetcher, CustomizableKeyFetcher { public static final String FETCHER_NAME = "Semantic Scholar Citations Fetcher"; + + private static final Logger LOGGER = LoggerFactory.getLogger(SemanticScholarCitationFetcher.class); + private static final String SEMANTIC_SCHOLAR_API = "https://api.semanticscholar.org/graph/v1/"; private static final Gson GSON = new Gson(); @@ -27,8 +35,8 @@ public SemanticScholarCitationFetcher(ImporterPreferences importerPreferences) { this.importerPreferences = importerPreferences; } - public String getAPIUrl(String entry_point, BibEntry entry) { - return SEMANTIC_SCHOLAR_API + "paper/" + "DOI:" + entry.getDOI().orElseThrow().asString() + "/" + entry_point + public String getAPIUrl(String entryPoint, BibEntry entry) { + return SEMANTIC_SCHOLAR_API + "paper/" + "DOI:" + entry.getDOI().orElseThrow().asString() + "/" + entryPoint + "?fields=" + "title,authors,year,citationCount,referenceCount,externalIds,publicationTypes,abstract,url" + "&limit=1000"; } @@ -42,6 +50,7 @@ public List searchCitedBy(BibEntry entry) throws FetcherException { URL citationsUrl; try { citationsUrl = URLUtil.create(getAPIUrl("citations", entry)); + LOGGER.debug("Cited URL {} ", citationsUrl); } catch (MalformedURLException e) { throw new FetcherException("Malformed URL", e); } @@ -66,15 +75,30 @@ public List searchCitedBy(BibEntry entry) throws FetcherException { URL referencesUrl; try { referencesUrl = URLUtil.create(getAPIUrl("references", entry)); + LOGGER.debug("Citing URL {} ", referencesUrl); } catch (MalformedURLException e) { throw new FetcherException("Malformed URL", e); } URLDownload urlDownload = new URLDownload(referencesUrl); importerPreferences.getApiKey(getName()).ifPresent(apiKey -> urlDownload.addHeader("x-api-key", apiKey)); - ReferencesResponse referencesResponse = GSON.fromJson(urlDownload.asString(), ReferencesResponse.class); + String response = urlDownload.asString(); + ReferencesResponse referencesResponse = GSON.fromJson(response, ReferencesResponse.class); if (referencesResponse.getData() == null) { + JsonNode json = JsonNode.of(response); + JsonNode disclaimerJson = json.getOrNull("citingPaperInfo.openAccessPdf.disclaimer"); + if (disclaimerJson != null) { + JsonMixed disclaimerNode = JsonMixed.of(disclaimerJson); + if (disclaimerNode.isString()) { + String disclaimer = disclaimerNode.string(); + LOGGER.debug("Received a disclaimer from Semantic Scholar: {}", disclaimer); + if (disclaimer.contains("'references'")) { + throw new FetcherException(Localization.lang("Restricted access to references: %0", disclaimer)); + } + } + } + return List.of(); } diff --git a/jablib/src/main/resources/l10n/JabRef_en.properties b/jablib/src/main/resources/l10n/JabRef_en.properties index 5b983088790..1e8c7d77492 100644 --- a/jablib/src/main/resources/l10n/JabRef_en.properties +++ b/jablib/src/main/resources/l10n/JabRef_en.properties @@ -1697,6 +1697,12 @@ Open\ one\ before\ citing.=Open one before citing. Select\ one\ before\ citing.=Select one before citing. Select\ some\ before\ citing.=Select some before citing. +Citation\ relations=Citation relations +Show\ articles\ related\ by\ citation=Show articles related by citation +Error\ while\ fetching\ cited\ entries\:\ %0=Error while fetching cited entries: %0 +Error\ while\ fetching\ citing\ entries\:\ %0=Error while fetching citing entries: %0 +Restricted\ access\ to\ references\:\ %0=Restricted access to references: %0 + Found\ identical\ ranges=Found identical ranges Found\ overlapping\ ranges=Found overlapping ranges Found\ touching\ ranges=Found touching ranges @@ -2809,9 +2815,7 @@ Restart\ search=Restart search Cancel\ search=Cancel search Select\ entry=Select entry Search\ aborted!=Search aborted! -Citation\ relations=Citation relations -Show\ articles\ related\ by\ citation=Show articles related by citation -Error\ while\ fetching\ citing\ entries\:\ %0=Error while fetching citing entries: %0 + Help\ on\ external\ applications=Help on external applications Identifier-based\ Web\ Search=Identifier-based Web Search diff --git a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java index f2ee7bc476b..b95a540f39e 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -6,6 +6,7 @@ import org.jabref.logic.citation.repository.BibEntryCitationsAndReferencesRepository; import org.jabref.logic.citation.repository.BibEntryRelationsRepositoryTestHelpers; +import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.fetcher.citation.CitationFetcher; import org.jabref.logic.importer.fetcher.citation.CitationFetcherHelpersForTest; import org.jabref.model.entry.BibEntry; @@ -51,7 +52,7 @@ private CitationFetcher createEmptyMockFetcher() { @Nested class CitationsTests { @Test - void serviceShouldSearchForCitations() { + void serviceShouldSearchForCitations() throws FetcherException { // GIVEN BibEntry cited = new BibEntry(); List citationsToReturn = List.of(new BibEntry()); @@ -61,14 +62,14 @@ void serviceShouldSearchForCitations() { SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(null, repository); // WHEN - List citations = searchService.searchCitations(cited); + List citations = searchService.searchCitedBy(cited); // THEN assertEquals(citationsToReturn, citations); } @Test - void serviceShouldCallTheFetcherForCitationsWhenRepositoryIsUpdatable() { + void serviceShouldCallTheFetcherForCitationsWhenRepositoryIsUpdatable() throws FetcherException { // GiVEN BibEntry cited = new BibEntry(); BibEntry newCitations = new BibEntry(); @@ -86,7 +87,7 @@ void serviceShouldCallTheFetcherForCitationsWhenRepositoryIsUpdatable() { SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN - List citations = searchService.searchCitations(cited); + List citations = searchService.searchCitedBy(cited); // THEN assertTrue(citationsDatabase.containsKey(cited)); @@ -95,7 +96,7 @@ void serviceShouldCallTheFetcherForCitationsWhenRepositoryIsUpdatable() { } @Test - void serviceShouldFetchCitationsIfRepositoryIsEmpty() { + void serviceShouldFetchCitationsIfRepositoryIsEmpty() throws FetcherException { BibEntry cited = new BibEntry(); BibEntry newCitations = new BibEntry(); List citationsToReturn = List.of(newCitations); @@ -105,7 +106,7 @@ void serviceShouldFetchCitationsIfRepositoryIsEmpty() { SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN - List citations = searchService.searchCitations(cited); + List citations = searchService.searchCitedBy(cited); // THEN assertTrue(citationsDatabase.containsKey(cited)); @@ -114,7 +115,7 @@ void serviceShouldFetchCitationsIfRepositoryIsEmpty() { } @Test - void insertingAnEmptyCitationsShouldBePossible() { + void insertingAnEmptyCitationsShouldBePossible() throws FetcherException { BibEntry cited = new BibEntry(); Map> citationsDatabase = new HashMap<>(); CitationFetcher fetcher = createEmptyMockFetcher(); @@ -122,7 +123,7 @@ void insertingAnEmptyCitationsShouldBePossible() { SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN - List citations = searchService.searchCitations(cited); + List citations = searchService.searchCitedBy(cited); // THEN assertTrue(citations.isEmpty()); @@ -134,7 +135,7 @@ void insertingAnEmptyCitationsShouldBePossible() { @Nested class ReferencesTests { @Test - void serviceShouldSearchForReferences() { + void serviceShouldSearchForReferences() throws FetcherException { // GIVEN BibEntry referencer = new BibEntry(); List referencesToReturn = List.of(new BibEntry()); @@ -144,14 +145,14 @@ void serviceShouldSearchForReferences() { SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(null, repository); // WHEN - List references = searchService.searchReferences(referencer); + List references = searchService.searchCites(referencer); // THEN assertEquals(referencesToReturn, references); } @Test - void serviceShouldCallTheFetcherForReferencesWhenRepositoryIsUpdatable() { + void serviceShouldCallTheFetcherForReferencesWhenRepositoryIsUpdatable() throws FetcherException { // GIVEN BibEntry referencer = new BibEntry(); BibEntry newReference = new BibEntry(); @@ -169,7 +170,7 @@ void serviceShouldCallTheFetcherForReferencesWhenRepositoryIsUpdatable() { SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN - List references = searchService.searchReferences(referencer); + List references = searchService.searchCites(referencer); // THEN assertTrue(referencesDatabase.containsKey(referencer)); @@ -178,7 +179,7 @@ void serviceShouldCallTheFetcherForReferencesWhenRepositoryIsUpdatable() { } @Test - void serviceShouldFetchReferencesIfRepositoryIsEmpty() { + void serviceShouldFetchReferencesIfRepositoryIsEmpty() throws FetcherException { BibEntry reference = new BibEntry(); BibEntry newCitations = new BibEntry(); List referencesToReturn = List.of(newCitations); @@ -190,7 +191,7 @@ void serviceShouldFetchReferencesIfRepositoryIsEmpty() { SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN - List references = searchService.searchReferences(reference); + List references = searchService.searchCites(reference); // THEN assertTrue(referencesDatabase.containsKey(reference)); @@ -199,7 +200,7 @@ void serviceShouldFetchReferencesIfRepositoryIsEmpty() { } @Test - void insertingAnEmptyReferencesShouldBePossible() { + void insertingAnEmptyReferencesShouldBePossible() throws FetcherException { BibEntry referencer = new BibEntry(); Map> referenceDatabase = new HashMap<>(); CitationFetcher fetcher = createEmptyMockFetcher(); @@ -209,7 +210,7 @@ void insertingAnEmptyReferencesShouldBePossible() { SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN - List citations = searchService.searchReferences(referencer); + List citations = searchService.searchCites(referencer); // THEN assertTrue(citations.isEmpty()); diff --git a/versions/build.gradle.kts b/versions/build.gradle.kts index cb095163f99..5df6869796d 100644 --- a/versions/build.gradle.kts +++ b/versions/build.gradle.kts @@ -118,6 +118,7 @@ dependencies.constraints { api("org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:3.1.10") api("org.hamcrest:hamcrest:3.0") api("org.hibernate.validator:hibernate-validator:9.0.1.Final") + api("org.hisp.dhis:json-tree:1.8") api("org.jabref:afterburner.fx:2.0.0") api("org.jabref:easybind:2.3.0") api("org.jetbrains:annotations:26.0.2") From 516528867a660f99425366fb9bf62ac1cfbf0889 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 15 Jul 2025 22:46:51 +0200 Subject: [PATCH 2/3] Add link --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25a6c445031..1ebb7c04d76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We added the field `monthfiled` to the default list of fields to resolve BibTeX-Strings for [#13375](https://github.com/JabRef/jabref/issues/13375) - We added a new ID based fetcher for [EuropePMC](https://europepmc.org/). [#13389](https://github.com/JabRef/jabref/pull/13389) - We added an initial [cite as you write](https://retorque.re/zotero-better-bibtex/citing/cayw/) endpoint. [#13187](https://github.com/JabRef/jabref/issues/13187) -- In case no citation relation information can be fetched, we show the data providers reason. +- In case no citation relation information can be fetched, we show the data providers reason. [#13549](https://github.com/JabRef/jabref/pull/13549) ### Changed From 7068b2513425408b2c69571697117c307c1fb6af Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 15 Jul 2025 22:50:43 +0200 Subject: [PATCH 3/3] Fix typo --- .../entryeditor/citationrelationtab/CitationRelationsTab.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jabgui/src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java b/jabgui/src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java index 921cb476e06..b4c48afa40f 100644 --- a/jabgui/src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java +++ b/jabgui/src/main/java/org/jabref/gui/entryeditor/citationrelationtab/CitationRelationsTab.java @@ -519,7 +519,7 @@ private void onSearchForRelationsSucceed(BibEntry entry, CheckListView