From 563b8ff59e23eb8ab3776e8057908f6e6fbb5ab3 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 15 Jul 2025 22:45:27 +0200 Subject: [PATCH 1/9] 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/9] 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/9] 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 Date: Mon, 28 Jul 2025 21:31:34 +0200 Subject: [PATCH 4/9] Remove json tree --- jablib/build.gradle.kts | 2 -- jablib/src/main/java/module-info.java | 1 - versions/build.gradle.kts | 1 - 3 files changed, 4 deletions(-) diff --git a/jablib/build.gradle.kts b/jablib/build.gradle.kts index 14751c3c18f..998df49b311 100644 --- a/jablib/build.gradle.kts +++ b/jablib/build.gradle.kts @@ -106,8 +106,6 @@ 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 95f9fb61c17..239439ef356 100644 --- a/jablib/src/main/java/module-info.java +++ b/jablib/src/main/java/module-info.java @@ -146,7 +146,6 @@ 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/versions/build.gradle.kts b/versions/build.gradle.kts index e47723cead7..8ce7df79e8f 100644 --- a/versions/build.gradle.kts +++ b/versions/build.gradle.kts @@ -119,7 +119,6 @@ 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 4d14dd848d71146eeda76182c7deccf743a00f65 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 28 Jul 2025 21:37:04 +0200 Subject: [PATCH 5/9] Add some comment --- .../citation/semanticscholar/SemanticScholarCitationFetcher.java | 1 + 1 file changed, 1 insertion(+) 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 4309289cd78..410fc5d3ff6 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 @@ -93,6 +93,7 @@ public List searchCitedBy(BibEntry entry) throws FetcherException { ReferencesResponse referencesResponse = GSON.fromJson(response, ReferencesResponse.class); if (referencesResponse.getData() == null) { + // Get error message from citingPaperInfo.openAccessPdf.disclaimer JSONObject responseObject = new JSONObject(response); Optional.ofNullable(responseObject.optJSONObject("citingPaperInfo")) .ifPresent(citingPaperInfo -> From 7c961b6e488b51c3480e5b3df335598da75a7bef Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 28 Jul 2025 21:40:00 +0200 Subject: [PATCH 6/9] flatMap magic --- .../SemanticScholarCitationFetcher.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) 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 410fc5d3ff6..b3865d04fd3 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 @@ -96,19 +96,15 @@ public List searchCitedBy(BibEntry entry) throws FetcherException { // Get error message from citingPaperInfo.openAccessPdf.disclaimer JSONObject responseObject = new JSONObject(response); Optional.ofNullable(responseObject.optJSONObject("citingPaperInfo")) - .ifPresent(citingPaperInfo -> - Optional.ofNullable(citingPaperInfo.optJSONObject("openAccessPdf")) - .ifPresent(openAccessPdf -> Optional.ofNullable(openAccessPdf.optString("disclaimer")) - .ifPresent(Unchecked.consumer(disclaimer -> { - LOGGER.debug("Received a disclaimer from Semantic Scholar: {}", disclaimer); - if (disclaimer.contains("references")) { - throw new FetcherException(Localization.lang("Restricted access to references: %0", disclaimer)); - } - } - ) - ) - ) - ); + .flatMap(citingPaperInfo -> Optional.ofNullable(citingPaperInfo.optJSONObject("openAccessPdf"))) + .flatMap(openAccessPdf -> Optional.ofNullable(openAccessPdf.optString("disclaimer"))) + .ifPresent(Unchecked.consumer(disclaimer -> { + 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(); } From 2c46f6e9939cf74295af7e3720cba99f7db59264 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 28 Jul 2025 21:44:31 +0200 Subject: [PATCH 7/9] Fix localization --- jablib/src/main/resources/l10n/JabRef_en.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jablib/src/main/resources/l10n/JabRef_en.properties b/jablib/src/main/resources/l10n/JabRef_en.properties index a5787b8e57d..d341ce34365 100644 --- a/jablib/src/main/resources/l10n/JabRef_en.properties +++ b/jablib/src/main/resources/l10n/JabRef_en.properties @@ -2817,9 +2817,8 @@ No\ articles\ found=No articles found Restart\ search=Restart search Cancel\ search=Cancel search Select\ entry=Select entry -Search\ aborted!=Search aborted! - 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 From 0c911d5870186c19ec3cb1353310fbf5f71e79c2 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 29 Jul 2025 01:28:23 +0200 Subject: [PATCH 8/9] Remove duplicate entries --- jablib/src/main/resources/l10n/JabRef_en.properties | 3 --- 1 file changed, 3 deletions(-) diff --git a/jablib/src/main/resources/l10n/JabRef_en.properties b/jablib/src/main/resources/l10n/JabRef_en.properties index d341ce34365..eab77bc5ecf 100644 --- a/jablib/src/main/resources/l10n/JabRef_en.properties +++ b/jablib/src/main/resources/l10n/JabRef_en.properties @@ -2819,9 +2819,6 @@ 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 From dafc4840ee78eabe395d5907a20a339639cf3e43 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Tue, 29 Jul 2025 01:53:13 +0200 Subject: [PATCH 9/9] Fix wrong caching of jbang --- .github/workflows/binaries.yml | 1 - .github/workflows/publish.yml | 1 - .github/workflows/run-openrewrite.yml | 1 - .github/workflows/tests-code.yml | 10 ---------- 4 files changed, 13 deletions(-) diff --git a/.github/workflows/binaries.yml b/.github/workflows/binaries.yml index 908a7c903a5..f1437e358a0 100644 --- a/.github/workflows/binaries.yml +++ b/.github/workflows/binaries.yml @@ -208,7 +208,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index aded3a2f01b..10d4722e0f8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -68,7 +68,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: diff --git a/.github/workflows/run-openrewrite.yml b/.github/workflows/run-openrewrite.yml index 66a815f7984..0595413e3f8 100644 --- a/.github/workflows/run-openrewrite.yml +++ b/.github/workflows/run-openrewrite.yml @@ -45,7 +45,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: diff --git a/.github/workflows/tests-code.yml b/.github/workflows/tests-code.yml index 20c37a8a891..56409776a92 100644 --- a/.github/workflows/tests-code.yml +++ b/.github/workflows/tests-code.yml @@ -65,7 +65,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -99,7 +98,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -134,7 +132,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -180,7 +177,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -253,7 +249,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -287,7 +282,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -338,7 +332,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -388,7 +381,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -425,7 +417,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: @@ -489,7 +480,6 @@ jobs: - name: Use cache uses: actions/cache@v4 with: - lookup-only: true path: ~/.jbang key: ${{ steps.cache-key.outputs.cache_key }} restore-keys: