From dcc6076db91c0f1d5bb6349595e283431157d106 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Mon, 7 Jul 2025 20:35:38 -0600 Subject: [PATCH 01/36] first changes --- .../fetcher/citation/CitationFetcher.java | 9 +++++++ .../semanticscholar/PaperDetails.java | 5 ++++ .../SemanticScholarCitationFetcher.java | 27 +++++++++++++++++++ .../model/entry/field/StandardField.java | 2 ++ 4 files changed, 43 insertions(+) diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index 959f5fa275a..0172019d687 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -1,6 +1,7 @@ package org.jabref.logic.importer.fetcher.citation; import java.util.List; +import java.util.Optional; import org.jabref.logic.importer.FetcherException; import org.jabref.model.entry.BibEntry; @@ -40,6 +41,14 @@ enum SearchType { */ List searchCiting(BibEntry entry) throws FetcherException; + /** + * Looks for hits which are cited by the given {@link BibEntry}. + * + * @param entry entry to search articles for + * @return @link BibEntry, which is matched by the query (may be empty) + */ + Optional searchCitationCount(BibEntry entry) throws FetcherException; + /** * Returns the localized name of this fetcher. * The title can be used to display the fetcher in the menu and in the side pane. diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/PaperDetails.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/PaperDetails.java index 1ab9085a5cc..1d1d0eec544 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/PaperDetails.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/PaperDetails.java @@ -160,6 +160,11 @@ public BibEntry toBibEntry() { bibEntry.setField(StandardField.ABSTRACT, getAbstract()); } + if(getCitationCount() != 0){ + bibEntry.setField(StandardField.CITATIONCOUNT, String.valueOf( getCitationCount())); + } + + return bibEntry; } 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..f82d9082c81 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 @@ -3,6 +3,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.List; +import java.util.Optional; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.ImporterPreferences; @@ -32,6 +33,11 @@ public String getAPIUrl(String entry_point, BibEntry entry) { + "?fields=" + "title,authors,year,citationCount,referenceCount,externalIds,publicationTypes,abstract,url" + "&limit=1000"; } + public String getAPIUrl(BibEntry entry) { + return SEMANTIC_SCHOLAR_API + "paper/" + "DOI:" + entry.getDOI().orElseThrow().asString() + + "?fields=" + "title,authors,year,citationCount,referenceCount,externalIds,publicationTypes,abstract,url" + + "&limit=1000"; + } @Override public List searchCitedBy(BibEntry entry) throws FetcherException { @@ -84,6 +90,27 @@ public List searchCitedBy(BibEntry entry) throws FetcherException { .map(referenceDataItem -> referenceDataItem.getCitedPaper().toBibEntry()).toList(); } + @Override + public Optional searchCitationCount(BibEntry entry) throws FetcherException { + if (entry.getDOI().isEmpty()) { + return Optional.empty(); + } + URL referencesUrl; + try { + referencesUrl = URLUtil.create(getAPIUrl(entry)); + } 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)); + ReferenceDataItem referencesResponse = GSON.fromJson(urlDownload.asString(), ReferenceDataItem.class); + + if (referencesResponse == null) { + return Optional.empty(); + } + return Optional.of(referencesResponse.getCitedPaper().toBibEntry()); + } + @Override public String getName() { return FETCHER_NAME; diff --git a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java index 5b192953b4e..c76a633791b 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -138,8 +138,10 @@ public enum StandardField implements Field { OWNER("owner"), TIMESTAMP("timestamp", FieldProperty.DATE), CREATIONDATE("creationdate", FieldProperty.DATE), + CITATIONCOUNT("citationcount", FieldProperty.NUMERIC), MODIFICATIONDATE("modificationdate", FieldProperty.DATE); + public static final Set AUTOMATIC_FIELDS = Set.of(OWNER, TIMESTAMP, CREATIONDATE, MODIFICATIONDATE); private static final Map NAME_TO_STANDARD_FIELD = new HashMap<>(); From 1a76c5736fec90ed5155faa51e340c3dd3f7b847 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Mon, 7 Jul 2025 21:21:13 -0600 Subject: [PATCH 02/36] partial change --- .../java/org/jabref/gui/entryeditor/SciteTab.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java b/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java index 50eb2e9f1b8..c149ba71d4f 100644 --- a/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java +++ b/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java @@ -5,9 +5,11 @@ import java.nio.charset.StandardCharsets; import javafx.geometry.HPos; +import javafx.geometry.Orientation; import javafx.scene.control.Hyperlink; import javafx.scene.control.Label; import javafx.scene.control.ProgressIndicator; +import javafx.scene.control.Separator; import javafx.scene.control.Tooltip; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; @@ -66,12 +68,20 @@ private void setSciteResultsPane() { switch (status) { case IN_PROGRESS -> sciteResultsPane.add(progressIndicator, 0, 0); - case FOUND -> + case FOUND ->{ viewModel.getCurrentResult().ifPresent(result -> sciteResultsPane.add(getTalliesPane(result), 0, 0)); + Separator separator = new Separator(); + separator.setOrientation(Orientation.HORIZONTAL); + sciteResultsPane.add(separator,0,1); + } case ERROR -> sciteResultsPane.add(getErrorPane(), 0, 0); } }); + + + + } @Override From aaef2ce5154b5b9e47697f16e88253a5e748b55c Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Fri, 11 Jul 2025 16:48:04 -0600 Subject: [PATCH 03/36] add fields to GUI --- .../org/jabref/gui/entryeditor/SciteTab.java | 10 ++--- .../jabref/gui/fieldeditors/FieldEditors.java | 4 +- .../CitationCountEditorViewModel.java | 37 +++++++++++++++++++ .../identifier/IdentifierEditor.java | 5 ++- .../model/entry/field/FieldFactory.java | 2 +- .../model/entry/field/FieldProperty.java | 1 + .../model/entry/field/StandardField.java | 2 +- .../identifier/CitationCountIdentifier.java | 15 ++++++++ 8 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java create mode 100644 jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java diff --git a/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java b/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java index c149ba71d4f..e7018a22a1b 100644 --- a/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java +++ b/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java @@ -70,18 +70,18 @@ private void setSciteResultsPane() { sciteResultsPane.add(progressIndicator, 0, 0); case FOUND ->{ viewModel.getCurrentResult().ifPresent(result -> sciteResultsPane.add(getTalliesPane(result), 0, 0)); - Separator separator = new Separator(); - separator.setOrientation(Orientation.HORIZONTAL); - sciteResultsPane.add(separator,0,1); } case ERROR -> sciteResultsPane.add(getErrorPane(), 0, 0); } }); + } - - + private void setCitationCountPane(){ + Separator separator = new Separator(); + separator.setOrientation(Orientation.HORIZONTAL); + sciteResultsPane.add(separator,0,1); } @Override diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java index ac5a7096f24..8767ca14100 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java @@ -72,10 +72,10 @@ public static FieldEditorFX getForField(final Field field, return new UrlEditor(field, suggestionProvider, fieldCheckers, undoAction, redoAction); } else if (fieldProperties.contains(FieldProperty.JOURNAL_NAME)) { return new JournalEditor(field, suggestionProvider, fieldCheckers, undoAction, redoAction); - } else if (fieldProperties.contains(FieldProperty.IDENTIFIER) && field != StandardField.PMID || field == StandardField.ISBN) { + } else if (fieldProperties.contains(FieldProperty.IDENTIFIER) && field != StandardField.PMID || field == StandardField.ISBN || field == StandardField.CITATIONCOUNT ) { // Identifier editor does not support PMID, therefore excluded at the condition above return new IdentifierEditor(field, suggestionProvider, fieldCheckers); - } else if (field == StandardField.ISSN) { + }else if (field == StandardField.ISSN) { return new ISSNEditor(field, suggestionProvider, fieldCheckers, undoAction, redoAction); } else if (field == StandardField.OWNER) { return new OwnerEditor(field, suggestionProvider, fieldCheckers, undoAction, redoAction); diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java new file mode 100644 index 00000000000..c7a8cc42407 --- /dev/null +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java @@ -0,0 +1,37 @@ +package org.jabref.gui.fieldeditors.identifier; + +import javax.swing.undo.UndoManager; + +import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; +import org.jabref.gui.autocompleter.SuggestionProvider; +import org.jabref.gui.preferences.GuiPreferences; +import org.jabref.logic.integrity.FieldCheckers; +import org.jabref.logic.util.TaskExecutor; +import org.jabref.model.entry.field.StandardField; +import org.jabref.model.entry.identifier.CitationCountIdentifier; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CitationCountEditorViewModel extends BaseIdentifierEditorViewModel { + public static final Logger LOGGER = LoggerFactory.getLogger(DoiIdentifierEditorViewModel.class); + + private final UndoManager undoManager; + private final StateManager stateManager; + + public CitationCountEditorViewModel(SuggestionProvider suggestionProvider, + FieldCheckers fieldCheckers, + DialogService dialogService, + TaskExecutor taskExecutor, + GuiPreferences preferences, + UndoManager undoManager, + StateManager stateManager){ + + super(StandardField.CITATIONCOUNT, suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager); + this.undoManager = undoManager; + this.stateManager = stateManager; + configure(false,true); + } + +} diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java index 105472c79be..99e56fd72b9 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java @@ -32,7 +32,7 @@ import static org.jabref.model.entry.field.StandardField.DOI; import static org.jabref.model.entry.field.StandardField.EPRINT; import static org.jabref.model.entry.field.StandardField.ISBN; - +import static org.jabref.model.entry.field.StandardField.CITATIONCOUNT; public class IdentifierEditor extends HBox implements FieldEditorFX { @FXML private BaseIdentifierEditorViewModel viewModel; @@ -63,6 +63,9 @@ public IdentifierEditor(Field field, this.viewModel = new ISBNIdentifierEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager, stateManager); case EPRINT -> this.viewModel = new EprintIdentifierEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager); + case CITATIONCOUNT -> + this.viewModel = new CitationCountEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager,stateManager); + // TODO: Add support for PMID case null, default -> { assert field != null; diff --git a/jablib/src/main/java/org/jabref/model/entry/field/FieldFactory.java b/jablib/src/main/java/org/jabref/model/entry/field/FieldFactory.java index 2b7f2788d43..bb5438f935e 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/FieldFactory.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/FieldFactory.java @@ -231,7 +231,7 @@ private static Set getAllFields() { * separate preferences object */ public static List getDefaultGeneralFields() { - List defaultGeneralFields = new ArrayList<>(Arrays.asList(StandardField.DOI, StandardField.CROSSREF, StandardField.KEYWORDS, StandardField.EPRINT, StandardField.URL, StandardField.FILE, StandardField.GROUPS, StandardField.OWNER, StandardField.TIMESTAMP)); + List defaultGeneralFields = new ArrayList<>(Arrays.asList(StandardField.DOI, StandardField.CITATIONCOUNT ,StandardField.CROSSREF, StandardField.KEYWORDS, StandardField.EPRINT, StandardField.URL, StandardField.FILE, StandardField.GROUPS, StandardField.OWNER, StandardField.TIMESTAMP)); defaultGeneralFields.addAll(EnumSet.allOf(SpecialField.class)); return defaultGeneralFields; } diff --git a/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java b/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java index 7dad6ca1faf..29d739b55ee 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java @@ -35,6 +35,7 @@ public enum FieldProperty { // Field content should be treated as data VERBATIM, + CITATIONCOUNT, YES_NO } diff --git a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java index c76a633791b..67a43b8c9d4 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -138,7 +138,7 @@ public enum StandardField implements Field { OWNER("owner"), TIMESTAMP("timestamp", FieldProperty.DATE), CREATIONDATE("creationdate", FieldProperty.DATE), - CITATIONCOUNT("citationcount", FieldProperty.NUMERIC), + CITATIONCOUNT("Citation Count", FieldProperty.CITATIONCOUNT), MODIFICATIONDATE("modificationdate", FieldProperty.DATE); diff --git a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java new file mode 100644 index 00000000000..cd4869056ba --- /dev/null +++ b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java @@ -0,0 +1,15 @@ +package org.jabref.model.entry.identifier; + +import java.net.URI; +import java.util.Optional; + +import org.jabref.model.entry.field.Field; + +public abstract class CitationCountIdentifier implements Identifier { + + @Override + public Field getDefaultField() { + return null; + } + +} From 150bc2c327b5a2dbe808e7a78125df5e6cfb1486 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Fri, 11 Jul 2025 18:09:04 -0600 Subject: [PATCH 04/36] finish change --- .../CitationCountEditorViewModel.java | 20 ++++++++++++++++++- .../identifier/IdentifierEditor.java | 5 ++++- .../SearchCitationsRelationsService.java | 13 ++++++++++++ .../fetcher/citation/CitationFetcher.java | 3 ++- .../semanticscholar/PaperDetails.java | 5 ----- .../SemanticScholarCitationFetcher.java | 6 +++--- 6 files changed, 41 insertions(+), 11 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java index c7a8cc42407..22f80a58b20 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java @@ -6,8 +6,13 @@ import org.jabref.gui.StateManager; import org.jabref.gui.autocompleter.SuggestionProvider; import org.jabref.gui.preferences.GuiPreferences; +import org.jabref.logic.citation.SearchCitationsRelationsService; +import org.jabref.logic.importer.fetcher.CrossRef; import org.jabref.logic.integrity.FieldCheckers; +import org.jabref.logic.l10n.Localization; +import org.jabref.logic.util.BackgroundTask; import org.jabref.logic.util.TaskExecutor; +import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.identifier.CitationCountIdentifier; @@ -19,6 +24,7 @@ public class CitationCountEditorViewModel extends BaseIdentifierEditorViewModel< private final UndoManager undoManager; private final StateManager stateManager; + private final SearchCitationsRelationsService searchCitationsRelationsService; public CitationCountEditorViewModel(SuggestionProvider suggestionProvider, FieldCheckers fieldCheckers, @@ -26,12 +32,24 @@ public CitationCountEditorViewModel(SuggestionProvider suggestionProvider, TaskExecutor taskExecutor, GuiPreferences preferences, UndoManager undoManager, - StateManager stateManager){ + StateManager stateManager, + SearchCitationsRelationsService searchCitationsRelationsService){ super(StandardField.CITATIONCOUNT, suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager); this.undoManager = undoManager; this.stateManager = stateManager; + this.searchCitationsRelationsService = searchCitationsRelationsService; configure(false,true); } + @Override + public void lookupIdentifier(BibEntry bibEntry) { + + BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(bibEntry)) + .onRunning(() -> identifierLookupInProgress.setValue(true)) + .onFinished(() -> identifierLookupInProgress.setValue(false)) + .onSuccess(identifier -> { + entry.setField(field, String.valueOf(identifier)); + }).executeWith(taskExecutor); + } } diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java index 99e56fd72b9..bae90e86116 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java @@ -19,6 +19,7 @@ import org.jabref.gui.fieldeditors.contextmenu.DefaultMenu; import org.jabref.gui.fieldeditors.contextmenu.EditorMenus; import org.jabref.gui.preferences.GuiPreferences; +import org.jabref.logic.citation.SearchCitationsRelationsService; import org.jabref.logic.integrity.FieldCheckers; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.TaskExecutor; @@ -46,6 +47,8 @@ public class IdentifierEditor extends HBox implements FieldEditorFX { @Inject private UndoManager undoManager; @Inject private StateManager stateManager; + @Inject private SearchCitationsRelationsService searchCitationsRelationsService; + private Optional entry = Optional.empty(); public IdentifierEditor(Field field, @@ -64,7 +67,7 @@ public IdentifierEditor(Field field, case EPRINT -> this.viewModel = new EprintIdentifierEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager); case CITATIONCOUNT -> - this.viewModel = new CitationCountEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager,stateManager); + this.viewModel = new CitationCountEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager,stateManager,searchCitationsRelationsService); // TODO: Add support for PMID case null, default -> { 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..051bfa02767 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -1,6 +1,7 @@ package org.jabref.logic.citation; import java.util.List; +import java.util.Optional; import org.jabref.logic.bibtex.FieldPreferences; import org.jabref.logic.citation.repository.BibEntryCitationsAndReferencesRepository; @@ -9,6 +10,7 @@ import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.ImporterPreferences; import org.jabref.logic.importer.fetcher.citation.CitationFetcher; +import org.jabref.logic.importer.fetcher.citation.semanticscholar.PaperDetails; import org.jabref.logic.importer.fetcher.citation.semanticscholar.SemanticScholarCitationFetcher; import org.jabref.logic.util.Directories; import org.jabref.model.entry.BibEntry; @@ -83,6 +85,17 @@ public List searchCitations(BibEntry cited) { return relationsRepository.readCitations(cited); } + public int getCitationCount(BibEntry citationCounted){ + Optional citationCountResult = null; + try { + citationCountResult = citationFetcher.searchCitationCount(citationCounted); + } catch (FetcherException e) { + LOGGER.error("Error while fetching citiation count for entry", e); + } + + return citationCountResult.map(PaperDetails::getCitationCount).orElse(0); + } + public void close() { relationsRepository.close(); } diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index 0172019d687..279bcd6309c 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -4,6 +4,7 @@ import java.util.Optional; import org.jabref.logic.importer.FetcherException; +import org.jabref.logic.importer.fetcher.citation.semanticscholar.PaperDetails; import org.jabref.model.entry.BibEntry; /** @@ -47,7 +48,7 @@ enum SearchType { * @param entry entry to search articles for * @return @link BibEntry, which is matched by the query (may be empty) */ - Optional searchCitationCount(BibEntry entry) throws FetcherException; + Optional searchCitationCount(BibEntry entry) throws FetcherException; /** * Returns the localized name of this fetcher. diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/PaperDetails.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/PaperDetails.java index 1d1d0eec544..1ab9085a5cc 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/PaperDetails.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/PaperDetails.java @@ -160,11 +160,6 @@ public BibEntry toBibEntry() { bibEntry.setField(StandardField.ABSTRACT, getAbstract()); } - if(getCitationCount() != 0){ - bibEntry.setField(StandardField.CITATIONCOUNT, String.valueOf( getCitationCount())); - } - - return bibEntry; } 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 f82d9082c81..1875de648c2 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 @@ -91,7 +91,7 @@ public List searchCitedBy(BibEntry entry) throws FetcherException { } @Override - public Optional searchCitationCount(BibEntry entry) throws FetcherException { + public Optional searchCitationCount(BibEntry entry) throws FetcherException { if (entry.getDOI().isEmpty()) { return Optional.empty(); } @@ -103,12 +103,12 @@ public Optional searchCitationCount(BibEntry entry) throws FetcherExce } URLDownload urlDownload = new URLDownload(referencesUrl); importerPreferences.getApiKey(getName()).ifPresent(apiKey -> urlDownload.addHeader("x-api-key", apiKey)); - ReferenceDataItem referencesResponse = GSON.fromJson(urlDownload.asString(), ReferenceDataItem.class); + PaperDetails referencesResponse = GSON.fromJson(urlDownload.asString(), PaperDetails.class); if (referencesResponse == null) { return Optional.empty(); } - return Optional.of(referencesResponse.getCitedPaper().toBibEntry()); + return Optional.of(referencesResponse); } @Override From fe6b48d43f5478c12000331219e8e4d48e6a3e4b Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Fri, 11 Jul 2025 18:38:42 -0600 Subject: [PATCH 05/36] fix citation count identifier --- .../jabref/model/entry/identifier/CitationCountIdentifier.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java index cd4869056ba..9016a637055 100644 --- a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java +++ b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java @@ -4,12 +4,13 @@ import java.util.Optional; import org.jabref.model.entry.field.Field; +import org.jabref.model.entry.field.StandardField; public abstract class CitationCountIdentifier implements Identifier { @Override public Field getDefaultField() { - return null; + return StandardField.CITATIONCOUNT; } } From 23fbd53c1568632c5f5011efb90a06c4b867cc45 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 07:35:57 -0600 Subject: [PATCH 06/36] adding tests --- .../CitationCountEditorViewModel.java | 6 +++-- .../SearchCitationsRelationsService.java | 20 ++++++++++------ .../SearchCitationsRelationsServiceTest.java | 21 +++++++++++----- .../CitationFetcherHelpersForTest.java | 11 ++++++++- .../SemanticScholarCitationFetcherTest.java | 24 +++++++++++++++++++ 5 files changed, 66 insertions(+), 16 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java index 22f80a58b20..952848f9431 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java @@ -1,5 +1,7 @@ package org.jabref.gui.fieldeditors.identifier; +import java.util.Optional; + import javax.swing.undo.UndoManager; import org.jabref.gui.DialogService; @@ -43,8 +45,8 @@ public CitationCountEditorViewModel(SuggestionProvider suggestionProvider, } @Override public void lookupIdentifier(BibEntry bibEntry) { - - BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(bibEntry)) + Optional fieldAux = entry.getField(field); + BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(bibEntry,fieldAux)) .onRunning(() -> identifierLookupInProgress.setValue(true)) .onFinished(() -> identifierLookupInProgress.setValue(false)) .onSuccess(identifier -> { 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 051bfa02767..fb1b50de232 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -85,15 +85,21 @@ public List searchCitations(BibEntry cited) { return relationsRepository.readCitations(cited); } - public int getCitationCount(BibEntry citationCounted){ + public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue){ + Optional citationCountResult = null; - try { - citationCountResult = citationFetcher.searchCitationCount(citationCounted); - } catch (FetcherException e) { - LOGGER.error("Error while fetching citiation count for entry", e); + boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) + || !actualFieldValue.isPresent(); + if (isFetchingAllowed) { + try { + citationCountResult = citationFetcher.searchCitationCount(citationCounted); + } catch ( + FetcherException e) { + LOGGER.error("Error while fetching citiation count for entry", e); + } + return citationCountResult.map(PaperDetails::getCitationCount).orElse(0); } - - return citationCountResult.map(PaperDetails::getCitationCount).orElse(0); + return Integer.valueOf( actualFieldValue.get()); } public void close() { 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..a04778877a9 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -3,11 +3,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.jabref.logic.citation.repository.BibEntryCitationsAndReferencesRepository; import org.jabref.logic.citation.repository.BibEntryRelationsRepositoryTestHelpers; import org.jabref.logic.importer.fetcher.citation.CitationFetcher; import org.jabref.logic.importer.fetcher.citation.CitationFetcherHelpersForTest; +import org.jabref.logic.importer.fetcher.citation.semanticscholar.PaperDetails; import org.jabref.model.entry.BibEntry; import org.junit.jupiter.api.Nested; @@ -21,7 +23,7 @@ class SearchCitationsRelationsServiceTest { /** * Creates a mock CitationFetcher that returns specific results for citations and references */ - private CitationFetcher createMockFetcher(BibEntry targetEntry, List citationsToReturn, List referencesToReturn) { + private CitationFetcher createMockFetcher(BibEntry targetEntry, List citationsToReturn, List referencesToReturn, Optional paperDetailsReturn) { return CitationFetcherHelpersForTest.Mocks.from( entry -> { if (entry == targetEntry) { @@ -34,6 +36,12 @@ private CitationFetcher createMockFetcher(BibEntry targetEntry, List c return referencesToReturn != null ? referencesToReturn : List.of(); } return List.of(); + }, + entry -> { + if (entry == targetEntry){ + return paperDetailsReturn != null ? paperDetailsReturn : Optional.empty(); + } + return Optional.empty(); } ); } @@ -44,7 +52,8 @@ private CitationFetcher createMockFetcher(BibEntry targetEntry, List c private CitationFetcher createEmptyMockFetcher() { return CitationFetcherHelpersForTest.Mocks.from( _ -> List.of(), - _ -> List.of() + _ -> List.of(), + _ -> Optional.empty() ); } @@ -74,7 +83,7 @@ void serviceShouldCallTheFetcherForCitationsWhenRepositoryIsUpdatable() { BibEntry newCitations = new BibEntry(); List citationsToReturn = List.of(newCitations); Map> citationsDatabase = HashMap.newHashMap(300); - CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null); + CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null,null); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( _ -> citationsToReturn, citationsDatabase::put, @@ -100,7 +109,7 @@ void serviceShouldFetchCitationsIfRepositoryIsEmpty() { BibEntry newCitations = new BibEntry(); List citationsToReturn = List.of(newCitations); Map> citationsDatabase = HashMap.newHashMap(300); - CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null); + CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null,null); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); @@ -157,7 +166,7 @@ void serviceShouldCallTheFetcherForReferencesWhenRepositoryIsUpdatable() { BibEntry newReference = new BibEntry(); List referencesToReturn = List.of(newReference); Map> referencesDatabase = new HashMap<>(); - CitationFetcher fetcher = createMockFetcher(referencer, null, referencesToReturn); + CitationFetcher fetcher = createMockFetcher(referencer, null, referencesToReturn,null); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( List::of, (_, _) -> { }, @@ -183,7 +192,7 @@ void serviceShouldFetchReferencesIfRepositoryIsEmpty() { BibEntry newCitations = new BibEntry(); List referencesToReturn = List.of(newCitations); Map> referencesDatabase = new HashMap<>(); - CitationFetcher fetcher = createMockFetcher(reference, null, referencesToReturn); + CitationFetcher fetcher = createMockFetcher(reference, null, referencesToReturn,null); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( null, referencesDatabase ); diff --git a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/CitationFetcherHelpersForTest.java b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/CitationFetcherHelpersForTest.java index b84e767e186..65d4b814165 100644 --- a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/CitationFetcherHelpersForTest.java +++ b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/CitationFetcherHelpersForTest.java @@ -1,15 +1,19 @@ package org.jabref.logic.importer.fetcher.citation; import java.util.List; +import java.util.Optional; import java.util.function.Function; +import org.jabref.logic.importer.FetcherException; +import org.jabref.logic.importer.fetcher.citation.semanticscholar.PaperDetails; import org.jabref.model.entry.BibEntry; public class CitationFetcherHelpersForTest { public static class Mocks { public static CitationFetcher from( Function> retrieveCitedBy, - Function> retrieveCiting + Function> retrieveCiting, + Function> retrieveCitationCount ) { return new CitationFetcher() { @Override @@ -22,6 +26,11 @@ public List searchCiting(BibEntry entry) { return retrieveCiting.apply(entry); } + @Override + public Optional searchCitationCount(BibEntry entry) throws FetcherException { + return retrieveCitationCount.apply(entry); + } + @Override public String getName() { return "Test citation fetcher"; diff --git a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java index c6f1e1e4e15..aedfd2949d9 100644 --- a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java +++ b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java @@ -1,6 +1,7 @@ package org.jabref.logic.importer.fetcher.citation.semanticscholar; import java.util.List; +import java.util.Optional; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.ImporterPreferences; @@ -13,8 +14,11 @@ import org.junit.jupiter.api.Test; import org.mockito.Answers; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.mock; +import static org.hamcrest.Matchers.greaterThan; @FetcherTest class SemanticScholarCitationFetcherTest { @@ -45,4 +49,24 @@ void smoke() throws FetcherException { // Paper has more than 400 cites, but server returns "null" as data assertNotEquals(null, result); } + + @Test + void smokeCitationCount() throws FetcherException { + BibEntry entry = new BibEntry(StandardEntryType.Article) + .withCitationKey("Macht_2007") + .withField(StandardField.AUTHOR, "Macht, Michael and Mueller, Jochen") + .withField(StandardField.TITLE, "Immediate effects of chocolate on experimentally induced mood states") + .withField(StandardField.JOURNALTITLE, "Appetite") + .withField(StandardField.DATE, "2007-11") + .withField(StandardField.VOLUME, "49") + .withField(StandardField.NUMBER, "3") + .withField(StandardField.PAGES, "667--674") + .withField(StandardField.DOI, "10.1016/j.appet.2007.05.004") + .withField(StandardField.ISSN, "0195-6663") + .withField(StandardField.PUBLISHER, "Elsevier BV"); + + Optional result = fetcher.searchCitationCount(entry); + assertNotNull(result.get()); + assertThat(result.get().getCitationCount(), greaterThan(0)); + } } From f4fa327c8b519d4f763f68bb80955eea28531f00 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 11:27:07 -0600 Subject: [PATCH 07/36] add more testing --- .../SearchCitationsRelationsServiceTest.java | 87 ++++++++++++++++++- ...ibEntryRelationsRepositoryTestHelpers.java | 5 +- 2 files changed, 86 insertions(+), 6 deletions(-) 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 a04778877a9..f04561ff214 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -110,7 +110,7 @@ void serviceShouldFetchCitationsIfRepositoryIsEmpty() { List citationsToReturn = List.of(newCitations); Map> citationsDatabase = HashMap.newHashMap(300); CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null,null); - BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null); + BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null,true); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN @@ -127,7 +127,7 @@ void insertingAnEmptyCitationsShouldBePossible() { BibEntry cited = new BibEntry(); Map> citationsDatabase = new HashMap<>(); CitationFetcher fetcher = createEmptyMockFetcher(); - BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null); + BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null,true); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN @@ -194,7 +194,7 @@ void serviceShouldFetchReferencesIfRepositoryIsEmpty() { Map> referencesDatabase = new HashMap<>(); CitationFetcher fetcher = createMockFetcher(reference, null, referencesToReturn,null); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referencesDatabase + null, referencesDatabase,true ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); @@ -213,7 +213,7 @@ void insertingAnEmptyReferencesShouldBePossible() { Map> referenceDatabase = new HashMap<>(); CitationFetcher fetcher = createEmptyMockFetcher(); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referenceDatabase + null, referenceDatabase,true ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); @@ -225,5 +225,84 @@ void insertingAnEmptyReferencesShouldBePossible() { assertTrue(referenceDatabase.containsKey(referencer)); assertTrue(referenceDatabase.get(referencer).isEmpty()); } + + @Test + void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse(){ + + int expectedResult = 0; + BibEntry referencer = new BibEntry(); + Map> referenceDatabase = new HashMap<>(); + CitationFetcher fetcher = createEmptyMockFetcher(); + BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( + null, referenceDatabase,true + ); + SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); + Optional field = Optional.empty(); + int citationsCount = searchService.getCitationCount(referencer,field); + assertEquals(expectedResult,citationsCount); + } + + @Test + void serviceShouldCorrectlyFetchCitationCountFiled(){ + int expectedResult = 3; + BibEntry reference = new BibEntry(); + PaperDetails paperDetails = new PaperDetails(); + paperDetails.setCitationCount(3); + Map> referencesDatabase = new HashMap<>(); + CitationFetcher fetcher = createMockFetcher(reference, null, null,Optional.of(paperDetails)); + + BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( + null, referencesDatabase,true + ); + SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); + Optional field = Optional.empty(); + int citationsCount = searchService.getCitationCount(reference,field); + assertEquals(expectedResult,citationsCount); + + } + + @Test + void serviceShouldUpdateBecauseIsisCitationsUpdatableFalse(){ + int expectedResult = 3; + BibEntry reference = new BibEntry(); + reference.setId("testDoi"); + PaperDetails paperDetails = new PaperDetails(); + paperDetails.setCitationCount(3); + Map> referencesDatabase = new HashMap<>(); + referencesDatabase.put(reference,List.of()); + CitationFetcher fetcher = createMockFetcher(reference, null, null,Optional.of(paperDetails)); + + BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( + null, referencesDatabase,false + ); + + SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); + Optional field = Optional.empty(); + int citationsCount = searchService.getCitationCount(reference,field); + assertEquals(expectedResult,citationsCount); + + } + + @Test + void serviceShouldNotUpdateBecauseFieldAndDoiExists(){ + int expectedResult = 1; + BibEntry reference = new BibEntry(); + reference.setId("testDoi"); + PaperDetails paperDetails = new PaperDetails(); + paperDetails.setCitationCount(3); + Map> referencesDatabase = new HashMap<>(); + referencesDatabase.put(reference,List.of()); + CitationFetcher fetcher = createMockFetcher(reference, null, null,Optional.of(paperDetails)); + + BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( + null, referencesDatabase,false + ); + + SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); + Optional field = Optional.of("1"); + int citationsCount = searchService.getCitationCount(reference,field); + assertEquals(expectedResult,citationsCount); + + } } } diff --git a/jablib/src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java b/jablib/src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java index 3be2ce09010..577154063cd 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java +++ b/jablib/src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java @@ -76,7 +76,7 @@ public void close() { } public static BibEntryCitationsAndReferencesRepository from( - Map> citationsDB, Map> referencesDB + Map> citationsDB, Map> referencesDB, boolean isCitationsUpdatable ) { return new BibEntryCitationsAndReferencesRepository() { @Override @@ -96,7 +96,7 @@ public boolean containsCitations(BibEntry entry) { @Override public boolean isCitationsUpdatable(BibEntry entry) { - return true; + return isCitationsUpdatable; } @Override @@ -125,5 +125,6 @@ public void close() { } }; } + } } From 44de54c559feab625ec7d718aa499ea62c6f9555 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 11:37:38 -0600 Subject: [PATCH 08/36] remove unwanted logic --- .../main/java/org/jabref/gui/entryeditor/SciteTab.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java b/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java index e7018a22a1b..b56a6fec33b 100644 --- a/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java +++ b/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java @@ -68,22 +68,14 @@ private void setSciteResultsPane() { switch (status) { case IN_PROGRESS -> sciteResultsPane.add(progressIndicator, 0, 0); - case FOUND ->{ + case FOUND -> viewModel.getCurrentResult().ifPresent(result -> sciteResultsPane.add(getTalliesPane(result), 0, 0)); - } case ERROR -> sciteResultsPane.add(getErrorPane(), 0, 0); } }); } - - private void setCitationCountPane(){ - Separator separator = new Separator(); - separator.setOrientation(Orientation.HORIZONTAL); - sciteResultsPane.add(separator,0,1); - } - @Override public boolean shouldShow(BibEntry entry) { return viewModel.shouldShow(); From 05aa416c6794784cabde651aa96c2b70eb8b10a7 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 11:59:15 -0600 Subject: [PATCH 09/36] add entry to change log --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22db2799aeb..153c934661a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv ## [Unreleased] ### Added - +- We added a new citiationCoun field on the General in order to track this value for a given paper [#13477](https://github.com/JabRef/jabref/issues/13477) - We introduced a settings parameter to manage citations' relations local storage time-to-live with a default value set to 30 days. [#11189](https://github.com/JabRef/jabref/issues/11189) - We distribute arm64 images for Linux. [#10842](https://github.com/JabRef/jabref/issues/10842) - When adding an entry to a library, a warning is displayed if said entry already exists in an active library. [#13261](https://github.com/JabRef/jabref/issues/13261) From 15baed1967647ba535dd4df53e07a2e68e9d1f4f Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 12:31:12 -0600 Subject: [PATCH 10/36] resolve comments --- .../logic/citation/SearchCitationsRelationsService.java | 4 ++-- .../logic/importer/fetcher/citation/CitationFetcher.java | 6 +++--- .../java/org/jabref/model/entry/field/StandardField.java | 2 +- .../logic/citation/SearchCitationsRelationsServiceTest.java | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) 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 fb1b50de232..a64d1fcb7ce 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -87,7 +87,7 @@ public List searchCitations(BibEntry cited) { public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue){ - Optional citationCountResult = null; + Optional citationCountResult = Optional.empty(); boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) || !actualFieldValue.isPresent(); if (isFetchingAllowed) { @@ -95,7 +95,7 @@ public int getCitationCount(BibEntry citationCounted, Optional actualFie citationCountResult = citationFetcher.searchCitationCount(citationCounted); } catch ( FetcherException e) { - LOGGER.error("Error while fetching citiation count for entry", e); + LOGGER.error("Error while fetching citation count for entry", e); } return citationCountResult.map(PaperDetails::getCitationCount).orElse(0); } diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index 279bcd6309c..8c7885c34a9 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -43,10 +43,10 @@ enum SearchType { List searchCiting(BibEntry entry) throws FetcherException; /** - * Looks for hits which are cited by the given {@link BibEntry}. + * get the paper details that includes citation count field for a given {@link BibEntry}. * - * @param entry entry to search articles for - * @return @link BibEntry, which is matched by the query (may be empty) + * @param entry entry to search citation count field + * @return @link Optional, paper details that includes citation count field (may be empty) */ Optional searchCitationCount(BibEntry entry) throws FetcherException; diff --git a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java index 67a43b8c9d4..e088e80ba16 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -138,7 +138,7 @@ public enum StandardField implements Field { OWNER("owner"), TIMESTAMP("timestamp", FieldProperty.DATE), CREATIONDATE("creationdate", FieldProperty.DATE), - CITATIONCOUNT("Citation Count", FieldProperty.CITATIONCOUNT), + CITATIONCOUNT("Citation count", FieldProperty.CITATIONCOUNT), MODIFICATIONDATE("modificationdate", FieldProperty.DATE); 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 f04561ff214..80c6dc4c6c4 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -243,7 +243,7 @@ void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse(){ } @Test - void serviceShouldCorrectlyFetchCitationCountFiled(){ + void serviceShouldCorrectlyFetchCitationCountField(){ int expectedResult = 3; BibEntry reference = new BibEntry(); PaperDetails paperDetails = new PaperDetails(); From 19923b89d90f26f7cb6ccd4a2f84f82c2665527a Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 12:40:58 -0600 Subject: [PATCH 11/36] resolve comments --- .../jabref/logic/importer/fetcher/citation/CitationFetcher.java | 2 +- .../main/java/org/jabref/model/entry/field/FieldProperty.java | 2 +- .../main/java/org/jabref/model/entry/field/StandardField.java | 2 +- .../logic/citation/SearchCitationsRelationsServiceTest.java | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index 8c7885c34a9..4b70a287380 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -43,7 +43,7 @@ enum SearchType { List searchCiting(BibEntry entry) throws FetcherException; /** - * get the paper details that includes citation count field for a given {@link BibEntry}. + * Get the paper details that includes citation count field for a given {@link BibEntry}. * * @param entry entry to search citation count field * @return @link Optional, paper details that includes citation count field (may be empty) diff --git a/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java b/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java index 29d739b55ee..476680c75a2 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java @@ -35,7 +35,7 @@ public enum FieldProperty { // Field content should be treated as data VERBATIM, - CITATIONCOUNT, + CITATION_COUNT, YES_NO } diff --git a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java index e088e80ba16..62f9a479054 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -138,7 +138,7 @@ public enum StandardField implements Field { OWNER("owner"), TIMESTAMP("timestamp", FieldProperty.DATE), CREATIONDATE("creationdate", FieldProperty.DATE), - CITATIONCOUNT("Citation count", FieldProperty.CITATIONCOUNT), + CITATIONCOUNT("Citation count", FieldProperty.CITATION_COUNT), MODIFICATIONDATE("modificationdate", FieldProperty.DATE); 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 80c6dc4c6c4..37065c5c95c 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -228,7 +228,6 @@ void insertingAnEmptyReferencesShouldBePossible() { @Test void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse(){ - int expectedResult = 0; BibEntry referencer = new BibEntry(); Map> referenceDatabase = new HashMap<>(); From db2ffd21571a7845a36b95f62f227e71dc0cc008 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 12:46:34 -0600 Subject: [PATCH 12/36] resolve conflicts --- .../jabref/logic/importer/fetcher/citation/CitationFetcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index 4b70a287380..eaf270ddd1c 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -46,7 +46,7 @@ enum SearchType { * Get the paper details that includes citation count field for a given {@link BibEntry}. * * @param entry entry to search citation count field - * @return @link Optional, paper details that includes citation count field (may be empty) + * @return returns a {@link Optional}, that includes citation count field (may be empty) */ Optional searchCitationCount(BibEntry entry) throws FetcherException; From cd836e770840bee5ca4b4bd6a85814bb61a8efa2 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 12:54:49 -0600 Subject: [PATCH 13/36] enhance citation count change log --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 153c934661a..c41181e50f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv ## [Unreleased] ### Added -- We added a new citiationCoun field on the General in order to track this value for a given paper [#13477](https://github.com/JabRef/jabref/issues/13477) +- We added a new citationCount field on the General tab, in order to track this value for a given paper. [#13477](https://github.com/JabRef/jabref/issues/13477) - We introduced a settings parameter to manage citations' relations local storage time-to-live with a default value set to 30 days. [#11189](https://github.com/JabRef/jabref/issues/11189) - We distribute arm64 images for Linux. [#10842](https://github.com/JabRef/jabref/issues/10842) - When adding an entry to a library, a warning is displayed if said entry already exists in an active library. [#13261](https://github.com/JabRef/jabref/issues/13261) From a90024c966fb14eccbb6e19248ea8399d0e7a23c Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 12:57:30 -0600 Subject: [PATCH 14/36] enhance citation count change log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c41181e50f4..c9da084eaa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv ## [Unreleased] ### Added + - We added a new citationCount field on the General tab, in order to track this value for a given paper. [#13477](https://github.com/JabRef/jabref/issues/13477) - We introduced a settings parameter to manage citations' relations local storage time-to-live with a default value set to 30 days. [#11189](https://github.com/JabRef/jabref/issues/11189) - We distribute arm64 images for Linux. [#10842](https://github.com/JabRef/jabref/issues/10842) From 9c3facb215bcc3855912a50c1419c533c77bde8b Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 13:14:26 -0600 Subject: [PATCH 15/36] change assertion style --- .../citation/SearchCitationsRelationsServiceTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 37065c5c95c..71c8e5a6059 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -238,7 +238,7 @@ void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse(){ SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); Optional field = Optional.empty(); int citationsCount = searchService.getCitationCount(referencer,field); - assertEquals(expectedResult,citationsCount); + assertEquals(citationsCount,expectedResult); } @Test @@ -256,7 +256,7 @@ void serviceShouldCorrectlyFetchCitationCountField(){ SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); Optional field = Optional.empty(); int citationsCount = searchService.getCitationCount(reference,field); - assertEquals(expectedResult,citationsCount); + assertEquals(citationsCount,expectedResult); } @@ -278,7 +278,7 @@ void serviceShouldUpdateBecauseIsisCitationsUpdatableFalse(){ SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); Optional field = Optional.empty(); int citationsCount = searchService.getCitationCount(reference,field); - assertEquals(expectedResult,citationsCount); + assertEquals(citationsCount,expectedResult); } @@ -300,7 +300,7 @@ void serviceShouldNotUpdateBecauseFieldAndDoiExists(){ SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); Optional field = Optional.of("1"); int citationsCount = searchService.getCitationCount(reference,field); - assertEquals(expectedResult,citationsCount); + assertEquals(citationsCount,expectedResult); } } From 84af44fa9adb1620643735842c2d8d8434cabfd8 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 13:27:07 -0600 Subject: [PATCH 16/36] resolve conflicts --- .../logic/citation/SearchCitationsRelationsService.java | 9 +++------ .../model/entry/identifier/CitationCountIdentifier.java | 7 ------- 2 files changed, 3 insertions(+), 13 deletions(-) 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 a64d1fcb7ce..2869c0364bd 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -85,23 +85,20 @@ public List searchCitations(BibEntry cited) { return relationsRepository.readCitations(cited); } - public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue){ - + public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue) { Optional citationCountResult = Optional.empty(); boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) || !actualFieldValue.isPresent(); if (isFetchingAllowed) { try { citationCountResult = citationFetcher.searchCitationCount(citationCounted); - } catch ( - FetcherException e) { + } catch (FetcherException e) { LOGGER.error("Error while fetching citation count for entry", e); } return citationCountResult.map(PaperDetails::getCitationCount).orElse(0); } - return Integer.valueOf( actualFieldValue.get()); + return Integer.valueOf( actualFieldValue.get()); } - public void close() { relationsRepository.close(); } diff --git a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java index 9016a637055..6bdec988e63 100644 --- a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java +++ b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java @@ -1,16 +1,9 @@ package org.jabref.model.entry.identifier; - -import java.net.URI; -import java.util.Optional; - import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.StandardField; - public abstract class CitationCountIdentifier implements Identifier { - @Override public Field getDefaultField() { return StandardField.CITATIONCOUNT; } - } From 1d265d3757d0fdd9bba43eff4013aaa7bb83b8a6 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 13:44:23 -0600 Subject: [PATCH 17/36] resolve conflicts --- .../SearchCitationsRelationsServiceTest.java | 63 +++++++++---------- 1 file changed, 30 insertions(+), 33 deletions(-) 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 71c8e5a6059..301e2e4603a 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -38,7 +38,7 @@ private CitationFetcher createMockFetcher(BibEntry targetEntry, List c return List.of(); }, entry -> { - if (entry == targetEntry){ + if (entry == targetEntry) { return paperDetailsReturn != null ? paperDetailsReturn : Optional.empty(); } return Optional.empty(); @@ -83,7 +83,7 @@ void serviceShouldCallTheFetcherForCitationsWhenRepositoryIsUpdatable() { BibEntry newCitations = new BibEntry(); List citationsToReturn = List.of(newCitations); Map> citationsDatabase = HashMap.newHashMap(300); - CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null,null); + CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null, null); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( _ -> citationsToReturn, citationsDatabase::put, @@ -109,8 +109,8 @@ void serviceShouldFetchCitationsIfRepositoryIsEmpty() { BibEntry newCitations = new BibEntry(); List citationsToReturn = List.of(newCitations); Map> citationsDatabase = HashMap.newHashMap(300); - CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null,null); - BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null,true); + CitationFetcher fetcher = createMockFetcher(cited, citationsToReturn, null, null); + BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null, true); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN @@ -127,7 +127,7 @@ void insertingAnEmptyCitationsShouldBePossible() { BibEntry cited = new BibEntry(); Map> citationsDatabase = new HashMap<>(); CitationFetcher fetcher = createEmptyMockFetcher(); - BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null,true); + BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from(citationsDatabase, null, true); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); // WHEN @@ -166,7 +166,7 @@ void serviceShouldCallTheFetcherForReferencesWhenRepositoryIsUpdatable() { BibEntry newReference = new BibEntry(); List referencesToReturn = List.of(newReference); Map> referencesDatabase = new HashMap<>(); - CitationFetcher fetcher = createMockFetcher(referencer, null, referencesToReturn,null); + CitationFetcher fetcher = createMockFetcher(referencer, null, referencesToReturn, null); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( List::of, (_, _) -> { }, @@ -192,9 +192,9 @@ void serviceShouldFetchReferencesIfRepositoryIsEmpty() { BibEntry newCitations = new BibEntry(); List referencesToReturn = List.of(newCitations); Map> referencesDatabase = new HashMap<>(); - CitationFetcher fetcher = createMockFetcher(reference, null, referencesToReturn,null); + CitationFetcher fetcher = createMockFetcher(reference, null, referencesToReturn, null); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referencesDatabase,true + null, referencesDatabase, true ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); @@ -213,7 +213,7 @@ void insertingAnEmptyReferencesShouldBePossible() { Map> referenceDatabase = new HashMap<>(); CitationFetcher fetcher = createEmptyMockFetcher(); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referenceDatabase,true + null, referenceDatabase, true ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); @@ -227,81 +227,78 @@ void insertingAnEmptyReferencesShouldBePossible() { } @Test - void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse(){ + void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse() { int expectedResult = 0; BibEntry referencer = new BibEntry(); Map> referenceDatabase = new HashMap<>(); CitationFetcher fetcher = createEmptyMockFetcher(); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referenceDatabase,true + null, referenceDatabase, true ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); Optional field = Optional.empty(); - int citationsCount = searchService.getCitationCount(referencer,field); - assertEquals(citationsCount,expectedResult); + int citationsCount = searchService.getCitationCount(referencer, field); + assertEquals(citationsCount, expectedResult); } @Test - void serviceShouldCorrectlyFetchCitationCountField(){ + void serviceShouldCorrectlyFetchCitationCountField() { int expectedResult = 3; BibEntry reference = new BibEntry(); PaperDetails paperDetails = new PaperDetails(); paperDetails.setCitationCount(3); Map> referencesDatabase = new HashMap<>(); - CitationFetcher fetcher = createMockFetcher(reference, null, null,Optional.of(paperDetails)); + CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(paperDetails)); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referencesDatabase,true + null, referencesDatabase, true ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); Optional field = Optional.empty(); - int citationsCount = searchService.getCitationCount(reference,field); - assertEquals(citationsCount,expectedResult); - + int citationsCount = searchService.getCitationCount(reference, field); + assertEquals(citationsCount, expectedResult); } @Test - void serviceShouldUpdateBecauseIsisCitationsUpdatableFalse(){ + void serviceShouldUpdateBecauseIsisCitationsUpdatableFalse() { int expectedResult = 3; BibEntry reference = new BibEntry(); reference.setId("testDoi"); PaperDetails paperDetails = new PaperDetails(); paperDetails.setCitationCount(3); Map> referencesDatabase = new HashMap<>(); - referencesDatabase.put(reference,List.of()); - CitationFetcher fetcher = createMockFetcher(reference, null, null,Optional.of(paperDetails)); + referencesDatabase.put(reference, List.of()); + CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(paperDetails)); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referencesDatabase,false + null, referencesDatabase, false ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); Optional field = Optional.empty(); - int citationsCount = searchService.getCitationCount(reference,field); - assertEquals(citationsCount,expectedResult); - + int citationsCount = searchService.getCitationCount(reference, field); + assertEquals(citationsCount, expectedResult); } @Test - void serviceShouldNotUpdateBecauseFieldAndDoiExists(){ + void serviceShouldNotUpdateBecauseFieldAndDoiExists() { int expectedResult = 1; BibEntry reference = new BibEntry(); reference.setId("testDoi"); PaperDetails paperDetails = new PaperDetails(); paperDetails.setCitationCount(3); Map> referencesDatabase = new HashMap<>(); - referencesDatabase.put(reference,List.of()); - CitationFetcher fetcher = createMockFetcher(reference, null, null,Optional.of(paperDetails)); + referencesDatabase.put(reference, List.of()); + CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(paperDetails)); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referencesDatabase,false + null, referencesDatabase, false ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); Optional field = Optional.of("1"); - int citationsCount = searchService.getCitationCount(reference,field); - assertEquals(citationsCount,expectedResult); - + int citationsCount = searchService.getCitationCount(reference, field); + assertEquals(citationsCount, expectedResult); } } } From 8bfc988c920d927d401ff59370295c4ffad99561 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 14:10:02 -0600 Subject: [PATCH 18/36] resolve conflicts --- .../logic/citation/SearchCitationsRelationsService.java | 5 +++-- .../logic/importer/fetcher/citation/CitationFetcher.java | 2 +- .../semanticscholar/SemanticScholarCitationFetcher.java | 1 + .../main/java/org/jabref/model/entry/field/FieldFactory.java | 2 +- .../model/entry/identifier/CitationCountIdentifier.java | 4 +++- .../repository/BibEntryRelationsRepositoryTestHelpers.java | 1 - 6 files changed, 9 insertions(+), 6 deletions(-) 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 2869c0364bd..c343a6bed88 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -88,7 +88,7 @@ public List searchCitations(BibEntry cited) { public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue) { Optional citationCountResult = Optional.empty(); boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) - || !actualFieldValue.isPresent(); + || !actualFieldValue.isEmpty(); if (isFetchingAllowed) { try { citationCountResult = citationFetcher.searchCitationCount(citationCounted); @@ -97,8 +97,9 @@ public int getCitationCount(BibEntry citationCounted, Optional actualFie } return citationCountResult.map(PaperDetails::getCitationCount).orElse(0); } - return Integer.valueOf( actualFieldValue.get()); + return Integer.valueOf(actualFieldValue.get()); } + public void close() { relationsRepository.close(); } diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index eaf270ddd1c..438d1c54a2d 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -46,7 +46,7 @@ enum SearchType { * Get the paper details that includes citation count field for a given {@link BibEntry}. * * @param entry entry to search citation count field - * @return returns a {@link Optional}, that includes citation count field (may be empty) + * @return returns a {@link PaperDetails}, that includes citation count field (may be empty) */ Optional searchCitationCount(BibEntry entry) throws FetcherException; 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 1875de648c2..9c0027bd818 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 @@ -33,6 +33,7 @@ public String getAPIUrl(String entry_point, BibEntry entry) { + "?fields=" + "title,authors,year,citationCount,referenceCount,externalIds,publicationTypes,abstract,url" + "&limit=1000"; } + public String getAPIUrl(BibEntry entry) { return SEMANTIC_SCHOLAR_API + "paper/" + "DOI:" + entry.getDOI().orElseThrow().asString() + "?fields=" + "title,authors,year,citationCount,referenceCount,externalIds,publicationTypes,abstract,url" diff --git a/jablib/src/main/java/org/jabref/model/entry/field/FieldFactory.java b/jablib/src/main/java/org/jabref/model/entry/field/FieldFactory.java index bb5438f935e..b1266e61b1d 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/FieldFactory.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/FieldFactory.java @@ -231,7 +231,7 @@ private static Set getAllFields() { * separate preferences object */ public static List getDefaultGeneralFields() { - List defaultGeneralFields = new ArrayList<>(Arrays.asList(StandardField.DOI, StandardField.CITATIONCOUNT ,StandardField.CROSSREF, StandardField.KEYWORDS, StandardField.EPRINT, StandardField.URL, StandardField.FILE, StandardField.GROUPS, StandardField.OWNER, StandardField.TIMESTAMP)); + List defaultGeneralFields = new ArrayList<>(Arrays.asList(StandardField.DOI, StandardField.CITATIONCOUNT, StandardField.CROSSREF, StandardField.KEYWORDS, StandardField.EPRINT, StandardField.URL, StandardField.FILE, StandardField.GROUPS, StandardField.OWNER, StandardField.TIMESTAMP)); defaultGeneralFields.addAll(EnumSet.allOf(SpecialField.class)); return defaultGeneralFields; } diff --git a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java index 6bdec988e63..27a04aef124 100644 --- a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java +++ b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java @@ -1,7 +1,9 @@ package org.jabref.model.entry.identifier; import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.StandardField; -public abstract class CitationCountIdentifier implements Identifier { + +public abstract class CitationCountIdentifier implements Identifier { + @Override public Field getDefaultField() { return StandardField.CITATIONCOUNT; diff --git a/jablib/src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java b/jablib/src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java index 577154063cd..1fe6cf42c8b 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java +++ b/jablib/src/test/java/org/jabref/logic/citation/repository/BibEntryRelationsRepositoryTestHelpers.java @@ -125,6 +125,5 @@ public void close() { } }; } - } } From 83709c9d985c2c2fb479a9f7fc6a57717709cbee Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 17:37:14 -0600 Subject: [PATCH 19/36] resolve test errors --- jablib/build.gradle.kts | 3 +- .../SearchCitationsRelationsServiceTest.java | 28 ++----------------- .../SemanticScholarCitationFetcherTest.java | 2 +- ...ficeCalcExportFormatContentSingleEntry.xml | 3 ++ 4 files changed, 9 insertions(+), 27 deletions(-) diff --git a/jablib/build.gradle.kts b/jablib/build.gradle.kts index 998df49b311..c59761a55fe 100644 --- a/jablib/build.gradle.kts +++ b/jablib/build.gradle.kts @@ -421,7 +421,8 @@ tasks.test { jvmArgs = listOf( "-javaagent:${mockitoAgent.asPath}", "--add-opens", "java.base/jdk.internal.ref=org.apache.pdfbox.io", - "--add-opens", "java.base/java.nio=org.apache.pdfbox.io" + "--add-opens", "java.base/java.nio=org.apache.pdfbox.io", + "--add-reads", "org.xmlunit.matchers=java.xml" ) } 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 301e2e4603a..8a67b79ee9b 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -260,43 +260,21 @@ void serviceShouldCorrectlyFetchCitationCountField() { } @Test - void serviceShouldUpdateBecauseIsisCitationsUpdatableFalse() { + void serviceShouldUpdateBecauseIsisCitationsUpdatableTrue() { int expectedResult = 3; BibEntry reference = new BibEntry(); - reference.setId("testDoi"); PaperDetails paperDetails = new PaperDetails(); paperDetails.setCitationCount(3); Map> referencesDatabase = new HashMap<>(); referencesDatabase.put(reference, List.of()); - CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(paperDetails)); - - BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referencesDatabase, false - ); - - SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); - Optional field = Optional.empty(); - int citationsCount = searchService.getCitationCount(reference, field); - assertEquals(citationsCount, expectedResult); - } - @Test - void serviceShouldNotUpdateBecauseFieldAndDoiExists() { - int expectedResult = 1; - BibEntry reference = new BibEntry(); - reference.setId("testDoi"); - PaperDetails paperDetails = new PaperDetails(); - paperDetails.setCitationCount(3); - Map> referencesDatabase = new HashMap<>(); - referencesDatabase.put(reference, List.of()); CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(paperDetails)); - BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( - null, referencesDatabase, false + null, referencesDatabase, true ); SearchCitationsRelationsService searchService = new SearchCitationsRelationsService(fetcher, repository); - Optional field = Optional.of("1"); + Optional field = Optional.empty(); int citationsCount = searchService.getCitationCount(reference, field); assertEquals(citationsCount, expectedResult); } diff --git a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java index aedfd2949d9..4677d948182 100644 --- a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java +++ b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java @@ -15,10 +15,10 @@ import org.mockito.Answers; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.mock; -import static org.hamcrest.Matchers.greaterThan; @FetcherTest class SemanticScholarCitationFetcherTest { diff --git a/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml b/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml index ac7e806de40..bb3912c3852 100644 --- a/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml +++ b/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml @@ -388,6 +388,9 @@ Creationdate + + Citation count + Modificationdate From 4333732146e4ead01554ddb5a7d59ae6d7ac7978 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 17:51:03 -0600 Subject: [PATCH 20/36] resolve conflicts --- .../src/main/java/org/jabref/gui/entryeditor/SciteTab.java | 4 +--- .../jabref/gui/fieldeditors/identifier/IdentifierEditor.java | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java b/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java index b56a6fec33b..50eb2e9f1b8 100644 --- a/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java +++ b/jabgui/src/main/java/org/jabref/gui/entryeditor/SciteTab.java @@ -5,11 +5,9 @@ import java.nio.charset.StandardCharsets; import javafx.geometry.HPos; -import javafx.geometry.Orientation; import javafx.scene.control.Hyperlink; import javafx.scene.control.Label; import javafx.scene.control.ProgressIndicator; -import javafx.scene.control.Separator; import javafx.scene.control.Tooltip; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; @@ -74,8 +72,8 @@ private void setSciteResultsPane() { sciteResultsPane.add(getErrorPane(), 0, 0); } }); - } + @Override public boolean shouldShow(BibEntry entry) { return viewModel.shouldShow(); diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java index bae90e86116..3437d32f25b 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java @@ -30,10 +30,11 @@ import com.airhacks.afterburner.views.ViewLoader; import jakarta.inject.Inject; +import static org.jabref.model.entry.field.StandardField.CITATIONCOUNT; import static org.jabref.model.entry.field.StandardField.DOI; import static org.jabref.model.entry.field.StandardField.EPRINT; import static org.jabref.model.entry.field.StandardField.ISBN; -import static org.jabref.model.entry.field.StandardField.CITATIONCOUNT; + public class IdentifierEditor extends HBox implements FieldEditorFX { @FXML private BaseIdentifierEditorViewModel viewModel; @@ -67,7 +68,7 @@ public IdentifierEditor(Field field, case EPRINT -> this.viewModel = new EprintIdentifierEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager); case CITATIONCOUNT -> - this.viewModel = new CitationCountEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager,stateManager,searchCitationsRelationsService); + this.viewModel = new CitationCountEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager, stateManager, searchCitationsRelationsService); // TODO: Add support for PMID case null, default -> { From 18f9de027505cb3f0f99e14defee296ad01e3134 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 22:17:48 -0600 Subject: [PATCH 21/36] fix branch --- .../gui/fieldeditors/CitationCountEditor.java | 88 +++++++++++++++++++ .../CitationCountEditorViewModel.java | 65 ++++++++++++++ .../jabref/gui/fieldeditors/FieldEditors.java | 6 +- .../CitationCountEditorViewModel.java | 57 ------------ .../identifier/IdentifierEditor.java | 7 -- .../gui/fieldeditors/CitationCountEditor.fxml | 23 +++++ .../SearchCitationsRelationsService.java | 2 +- 7 files changed, 181 insertions(+), 67 deletions(-) create mode 100644 jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java create mode 100644 jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java delete mode 100644 jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java create mode 100644 jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java new file mode 100644 index 00000000000..6858ea10436 --- /dev/null +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java @@ -0,0 +1,88 @@ +package org.jabref.gui.fieldeditors; + +import java.util.Optional; + +import javax.swing.undo.UndoManager; + +import javafx.fxml.FXML; +import javafx.scene.Parent; +import javafx.scene.control.Button; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.HBox; + +import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; +import org.jabref.gui.autocompleter.SuggestionProvider; +import org.jabref.gui.fieldeditors.contextmenu.DefaultMenu; +import org.jabref.gui.preferences.GuiPreferences; +import org.jabref.logic.citation.SearchCitationsRelationsService; +import org.jabref.logic.integrity.FieldCheckers; +import org.jabref.logic.l10n.Localization; +import org.jabref.logic.util.TaskExecutor; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.Field; + +import com.airhacks.afterburner.injection.Injector; +import com.airhacks.afterburner.views.ViewLoader; +import jakarta.inject.Inject; + +public class CitationCountEditor extends HBox implements FieldEditorFX { + @FXML private CitationCountEditorViewModel viewModel; + @FXML private EditorTextField textField; + @FXML private Button fetchCitationCountButton; + + @Inject private DialogService dialogService; + @Inject private GuiPreferences preferences; + @Inject private UndoManager undoManager; + @Inject private TaskExecutor taskExecutor; + @Inject private StateManager stateManager; + @Inject private SearchCitationsRelationsService searchCitationsRelationsService; + + private Optional entry = Optional.empty(); + public CitationCountEditor(Field field, + SuggestionProvider suggestionProvider, + FieldCheckers fieldCheckers) { + Injector.registerExistingAndInject(this); + this.viewModel = new CitationCountEditorViewModel( + field, + suggestionProvider, + fieldCheckers, + taskExecutor, + dialogService, + undoManager, + stateManager, + preferences, + searchCitationsRelationsService); + + ViewLoader.view(this) + .root(this) + .load(); + + textField.textProperty().bindBidirectional(viewModel.textProperty()); + + fetchCitationCountButton.setTooltip( + new Tooltip(Localization.lang("Look up %0", field.getDisplayName()))); + textField.initContextMenu(new DefaultMenu(textField), preferences.getKeyBindingRepository()); + new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textField); + } + + @FXML + private void fetchCitationCount() { + this.entry.ifPresent(viewModel::getCitationCount); + } + + public CitationCountEditorViewModel getViewModel() { + return viewModel; + } + + @Override + public void bindToEntry(BibEntry entry) { + this.entry = Optional.of(entry); + viewModel.bindToEntry(entry); + } + + @Override + public Parent getNode() { + return this; + } +} diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java new file mode 100644 index 00000000000..0d6034f47d6 --- /dev/null +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java @@ -0,0 +1,65 @@ +package org.jabref.gui.fieldeditors; + +import java.util.Optional; + +import javax.swing.undo.UndoManager; + +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; + +import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; +import org.jabref.gui.autocompleter.SuggestionProvider; +import org.jabref.gui.preferences.GuiPreferences; +import org.jabref.logic.citation.SearchCitationsRelationsService; +import org.jabref.logic.integrity.FieldCheckers; +import org.jabref.logic.util.BackgroundTask; +import org.jabref.logic.util.TaskExecutor; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.Field; + +public class CitationCountEditorViewModel extends AbstractEditorViewModel { + protected final BooleanProperty fetchCitationCountInProgress = new SimpleBooleanProperty(false); + private final TaskExecutor taskExecutor; + private final DialogService dialogService; + private final UndoManager undoManager; + private final StateManager stateManager; + private final GuiPreferences preferences; + private final SearchCitationsRelationsService searchCitationsRelationsService; + public CitationCountEditorViewModel( + Field field, + SuggestionProvider suggestionProvider, + FieldCheckers fieldCheckers, + TaskExecutor taskExecutor, + DialogService dialogService, + UndoManager undoManager, + StateManager stateManager, + GuiPreferences preferences, + SearchCitationsRelationsService searchCitationsRelationsService) { + super(field, suggestionProvider, fieldCheckers, undoManager); + this.taskExecutor = taskExecutor; + this.dialogService = dialogService; + this.undoManager = undoManager; + this.stateManager = stateManager; + this.preferences = preferences; + this.searchCitationsRelationsService = searchCitationsRelationsService; + } + + public BooleanProperty fetchCitationCountInProgressProperty() { + return fetchCitationCountInProgress; + } + + public boolean getFetchCitationCountInProgress() { + return fetchCitationCountInProgress.get(); + } + + public void getCitationCount(BibEntry bibEntry) { + Optional fieldAux = entry.getField(field); + BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(bibEntry, fieldAux)) + .onRunning(() -> fetchCitationCountInProgress.setValue(true)) + .onFinished(() -> fetchCitationCountInProgress.setValue(false)) + .onSuccess(identifier -> { + entry.setField(field, String.valueOf(identifier)); + }).executeWith(taskExecutor); + } +} diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java index 8767ca14100..9583f0e87c2 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java @@ -72,10 +72,12 @@ public static FieldEditorFX getForField(final Field field, return new UrlEditor(field, suggestionProvider, fieldCheckers, undoAction, redoAction); } else if (fieldProperties.contains(FieldProperty.JOURNAL_NAME)) { return new JournalEditor(field, suggestionProvider, fieldCheckers, undoAction, redoAction); - } else if (fieldProperties.contains(FieldProperty.IDENTIFIER) && field != StandardField.PMID || field == StandardField.ISBN || field == StandardField.CITATIONCOUNT ) { + } else if (fieldProperties.contains(FieldProperty.IDENTIFIER) && field != StandardField.PMID || field == StandardField.ISBN) { // Identifier editor does not support PMID, therefore excluded at the condition above return new IdentifierEditor(field, suggestionProvider, fieldCheckers); - }else if (field == StandardField.ISSN) { + } else if (field == StandardField.CITATIONCOUNT) { + return new CitationCountEditor(field, suggestionProvider, fieldCheckers); + } else if (field == StandardField.ISSN) { return new ISSNEditor(field, suggestionProvider, fieldCheckers, undoAction, redoAction); } else if (field == StandardField.OWNER) { return new OwnerEditor(field, suggestionProvider, fieldCheckers, undoAction, redoAction); diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java deleted file mode 100644 index 952848f9431..00000000000 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/CitationCountEditorViewModel.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.jabref.gui.fieldeditors.identifier; - -import java.util.Optional; - -import javax.swing.undo.UndoManager; - -import org.jabref.gui.DialogService; -import org.jabref.gui.StateManager; -import org.jabref.gui.autocompleter.SuggestionProvider; -import org.jabref.gui.preferences.GuiPreferences; -import org.jabref.logic.citation.SearchCitationsRelationsService; -import org.jabref.logic.importer.fetcher.CrossRef; -import org.jabref.logic.integrity.FieldCheckers; -import org.jabref.logic.l10n.Localization; -import org.jabref.logic.util.BackgroundTask; -import org.jabref.logic.util.TaskExecutor; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.field.StandardField; -import org.jabref.model.entry.identifier.CitationCountIdentifier; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CitationCountEditorViewModel extends BaseIdentifierEditorViewModel { - public static final Logger LOGGER = LoggerFactory.getLogger(DoiIdentifierEditorViewModel.class); - - private final UndoManager undoManager; - private final StateManager stateManager; - private final SearchCitationsRelationsService searchCitationsRelationsService; - - public CitationCountEditorViewModel(SuggestionProvider suggestionProvider, - FieldCheckers fieldCheckers, - DialogService dialogService, - TaskExecutor taskExecutor, - GuiPreferences preferences, - UndoManager undoManager, - StateManager stateManager, - SearchCitationsRelationsService searchCitationsRelationsService){ - - super(StandardField.CITATIONCOUNT, suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager); - this.undoManager = undoManager; - this.stateManager = stateManager; - this.searchCitationsRelationsService = searchCitationsRelationsService; - configure(false,true); - } - @Override - public void lookupIdentifier(BibEntry bibEntry) { - Optional fieldAux = entry.getField(field); - BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(bibEntry,fieldAux)) - .onRunning(() -> identifierLookupInProgress.setValue(true)) - .onFinished(() -> identifierLookupInProgress.setValue(false)) - .onSuccess(identifier -> { - entry.setField(field, String.valueOf(identifier)); - }).executeWith(taskExecutor); - } - -} diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java index 3437d32f25b..c603f7b1b95 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/identifier/IdentifierEditor.java @@ -19,7 +19,6 @@ import org.jabref.gui.fieldeditors.contextmenu.DefaultMenu; import org.jabref.gui.fieldeditors.contextmenu.EditorMenus; import org.jabref.gui.preferences.GuiPreferences; -import org.jabref.logic.citation.SearchCitationsRelationsService; import org.jabref.logic.integrity.FieldCheckers; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.TaskExecutor; @@ -30,7 +29,6 @@ import com.airhacks.afterburner.views.ViewLoader; import jakarta.inject.Inject; -import static org.jabref.model.entry.field.StandardField.CITATIONCOUNT; import static org.jabref.model.entry.field.StandardField.DOI; import static org.jabref.model.entry.field.StandardField.EPRINT; import static org.jabref.model.entry.field.StandardField.ISBN; @@ -47,9 +45,6 @@ public class IdentifierEditor extends HBox implements FieldEditorFX { @Inject private GuiPreferences preferences; @Inject private UndoManager undoManager; @Inject private StateManager stateManager; - - @Inject private SearchCitationsRelationsService searchCitationsRelationsService; - private Optional entry = Optional.empty(); public IdentifierEditor(Field field, @@ -67,8 +62,6 @@ public IdentifierEditor(Field field, this.viewModel = new ISBNIdentifierEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager, stateManager); case EPRINT -> this.viewModel = new EprintIdentifierEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager); - case CITATIONCOUNT -> - this.viewModel = new CitationCountEditorViewModel(suggestionProvider, fieldCheckers, dialogService, taskExecutor, preferences, undoManager, stateManager, searchCitationsRelationsService); // TODO: Add support for PMID case null, default -> { diff --git a/jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml b/jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml new file mode 100644 index 00000000000..73e7f7e6940 --- /dev/null +++ b/jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + 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 c343a6bed88..c8a4b0402eb 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -88,7 +88,7 @@ public List searchCitations(BibEntry cited) { public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue) { Optional citationCountResult = Optional.empty(); boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) - || !actualFieldValue.isEmpty(); + || actualFieldValue.isEmpty(); if (isFetchingAllowed) { try { citationCountResult = citationFetcher.searchCitationCount(citationCounted); From 91c8c621b25633dbfde145bc0938f1ccb7c0a8e0 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 23:39:34 -0600 Subject: [PATCH 22/36] fix test --- ...ficeCalcExportFormatContentSingleEntry.xml | 234 +++++++++--------- 1 file changed, 118 insertions(+), 116 deletions(-) diff --git a/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml b/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml index bb3912c3852..f4ad981fbfd 100644 --- a/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml +++ b/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml @@ -403,380 +403,382 @@ 7 - + - + - + New York, NY, USA - + - + - + - + - + - + Tony Clear - + - + - + - + - + - + - + - + - + - + - + - + - + http://doi.acm.org/10.1145/820127.820136 - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + 0097-8418 - + - + - + SIGCSE Bull. - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + 4 - + - + - + 13--14 - + - + - + - + - + - + ACM - + - + - + - + - + - + - + - + - + - + - + - + - + - + - Design and usability in security systems: daily life as a context of - use? + Design and usability in security systems: daily life as a context of use? - + - + - + - + - + - + - + - + 34 - + 2002 - + - + - + - + - + - + - + - + - + - + - + - + + + + From 0cf385004bd8463bfd026cdb03c42af2dadbdfe4 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sat, 12 Jul 2025 23:56:45 -0600 Subject: [PATCH 23/36] remove unused class --- .../entry/identifier/CitationCountIdentifier.java | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java diff --git a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java b/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java deleted file mode 100644 index 27a04aef124..00000000000 --- a/jablib/src/main/java/org/jabref/model/entry/identifier/CitationCountIdentifier.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.jabref.model.entry.identifier; -import org.jabref.model.entry.field.Field; -import org.jabref.model.entry.field.StandardField; - -public abstract class CitationCountIdentifier implements Identifier { - - @Override - public Field getDefaultField() { - return StandardField.CITATIONCOUNT; - } -} From e1928d8fb35a9d0bc71cbc3c499c0c8ad23ededc Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Sun, 13 Jul 2025 06:10:38 -0600 Subject: [PATCH 24/36] resolve comment --- .../logic/citation/SearchCitationsRelationsService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 c8a4b0402eb..20af05096de 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -86,7 +86,7 @@ public List searchCitations(BibEntry cited) { } public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue) { - Optional citationCountResult = Optional.empty(); + Optional citationCountResult = null; boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) || actualFieldValue.isEmpty(); if (isFetchingAllowed) { @@ -97,7 +97,7 @@ public int getCitationCount(BibEntry citationCounted, Optional actualFie } return citationCountResult.map(PaperDetails::getCitationCount).orElse(0); } - return Integer.valueOf(actualFieldValue.get()); + return Integer.parseInt(actualFieldValue.get()); } public void close() { From 18e51bde2bd1db89903b3a9d8cd664716fc659fe Mon Sep 17 00:00:00 2001 From: SalvadorRomo Date: Mon, 14 Jul 2025 08:35:00 -0600 Subject: [PATCH 25/36] Update CHANGELOG.md Co-authored-by: Oliver Kopp --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9da084eaa5..eaba09787ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv ### Added -- We added a new citationCount field on the General tab, in order to track this value for a given paper. [#13477](https://github.com/JabRef/jabref/issues/13477) +- We added a field for fhe citation count field on the General tab. [#13477](https://github.com/JabRef/jabref/issues/13477) - We introduced a settings parameter to manage citations' relations local storage time-to-live with a default value set to 30 days. [#11189](https://github.com/JabRef/jabref/issues/11189) - We distribute arm64 images for Linux. [#10842](https://github.com/JabRef/jabref/issues/10842) - When adding an entry to a library, a warning is displayed if said entry already exists in an active library. [#13261](https://github.com/JabRef/jabref/issues/13261) From d12e8e449164d297293a1967048967ad3fdacc51 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Mon, 14 Jul 2025 10:26:39 -0600 Subject: [PATCH 26/36] resolve comments --- .../CitationCountEditorViewModel.java | 2 ++ jablib/build.gradle.kts | 3 +-- .../SearchCitationsRelationsService.java | 8 +++---- .../fetcher/citation/CitationFetcher.java | 2 +- .../SemanticScholarCitationFetcher.java | 10 ++++----- .../model/entry/field/FieldProperty.java | 2 -- .../model/entry/field/StandardField.java | 3 +-- .../SearchCitationsRelationsServiceTest.java | 22 +++++++++---------- .../CitationFetcherHelpersForTest.java | 5 ++--- .../SemanticScholarCitationFetcherTest.java | 4 ++-- 10 files changed, 28 insertions(+), 33 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java index 0d6034f47d6..4f71cf4f50e 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java @@ -13,6 +13,7 @@ import org.jabref.gui.preferences.GuiPreferences; import org.jabref.logic.citation.SearchCitationsRelationsService; import org.jabref.logic.integrity.FieldCheckers; +import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.BackgroundTask; import org.jabref.logic.util.TaskExecutor; import org.jabref.model.entry.BibEntry; @@ -58,6 +59,7 @@ public void getCitationCount(BibEntry bibEntry) { BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(bibEntry, fieldAux)) .onRunning(() -> fetchCitationCountInProgress.setValue(true)) .onFinished(() -> fetchCitationCountInProgress.setValue(false)) + .onFailure(e -> dialogService.showErrorDialogAndWait(Localization.lang("Error in getting Citation count"), e)) .onSuccess(identifier -> { entry.setField(field, String.valueOf(identifier)); }).executeWith(taskExecutor); diff --git a/jablib/build.gradle.kts b/jablib/build.gradle.kts index c59761a55fe..998df49b311 100644 --- a/jablib/build.gradle.kts +++ b/jablib/build.gradle.kts @@ -421,8 +421,7 @@ tasks.test { jvmArgs = listOf( "-javaagent:${mockitoAgent.asPath}", "--add-opens", "java.base/jdk.internal.ref=org.apache.pdfbox.io", - "--add-opens", "java.base/java.nio=org.apache.pdfbox.io", - "--add-reads", "org.xmlunit.matchers=java.xml" + "--add-opens", "java.base/java.nio=org.apache.pdfbox.io" ) } 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 20af05096de..21d9faa0861 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -10,7 +10,6 @@ import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.ImporterPreferences; import org.jabref.logic.importer.fetcher.citation.CitationFetcher; -import org.jabref.logic.importer.fetcher.citation.semanticscholar.PaperDetails; import org.jabref.logic.importer.fetcher.citation.semanticscholar.SemanticScholarCitationFetcher; import org.jabref.logic.util.Directories; import org.jabref.model.entry.BibEntry; @@ -85,8 +84,8 @@ public List searchCitations(BibEntry cited) { return relationsRepository.readCitations(cited); } - public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue) { - Optional citationCountResult = null; + public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue) throws FetcherException { + Optional citationCountResult = Optional.empty(); boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) || actualFieldValue.isEmpty(); if (isFetchingAllowed) { @@ -94,8 +93,9 @@ public int getCitationCount(BibEntry citationCounted, Optional actualFie citationCountResult = citationFetcher.searchCitationCount(citationCounted); } catch (FetcherException e) { LOGGER.error("Error while fetching citation count for entry", e); + throw e; } - return citationCountResult.map(PaperDetails::getCitationCount).orElse(0); + return citationCountResult.orElse(0); } return Integer.parseInt(actualFieldValue.get()); } diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index 438d1c54a2d..72f35294d0c 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -48,7 +48,7 @@ enum SearchType { * @param entry entry to search citation count field * @return returns a {@link PaperDetails}, that includes citation count field (may be empty) */ - Optional searchCitationCount(BibEntry entry) throws FetcherException; + Optional searchCitationCount(BibEntry entry) throws FetcherException; /** * Returns the localized name of this fetcher. 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 9c0027bd818..475b1d8975d 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 @@ -34,9 +34,9 @@ public String getAPIUrl(String entry_point, BibEntry entry) { + "&limit=1000"; } - public String getAPIUrl(BibEntry entry) { + public String getUrlForCitationCount(BibEntry entry) { return SEMANTIC_SCHOLAR_API + "paper/" + "DOI:" + entry.getDOI().orElseThrow().asString() - + "?fields=" + "title,authors,year,citationCount,referenceCount,externalIds,publicationTypes,abstract,url" + + "?fields=" + "citationCount" + "&limit=1000"; } @@ -92,13 +92,13 @@ public List searchCitedBy(BibEntry entry) throws FetcherException { } @Override - public Optional searchCitationCount(BibEntry entry) throws FetcherException { + public Optional searchCitationCount(BibEntry entry) throws FetcherException { if (entry.getDOI().isEmpty()) { return Optional.empty(); } URL referencesUrl; try { - referencesUrl = URLUtil.create(getAPIUrl(entry)); + referencesUrl = URLUtil.create(getUrlForCitationCount(entry)); } catch (MalformedURLException e) { throw new FetcherException("Malformed URL", e); } @@ -109,7 +109,7 @@ public Optional searchCitationCount(BibEntry entry) throws Fetcher if (referencesResponse == null) { return Optional.empty(); } - return Optional.of(referencesResponse); + return Optional.of(referencesResponse.getCitationCount()); } @Override diff --git a/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java b/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java index 476680c75a2..ef008e17b06 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java @@ -35,7 +35,5 @@ public enum FieldProperty { // Field content should be treated as data VERBATIM, - CITATION_COUNT, - YES_NO } diff --git a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java index 62f9a479054..0c4c071a6a3 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -138,10 +138,9 @@ public enum StandardField implements Field { OWNER("owner"), TIMESTAMP("timestamp", FieldProperty.DATE), CREATIONDATE("creationdate", FieldProperty.DATE), - CITATIONCOUNT("Citation count", FieldProperty.CITATION_COUNT), + CITATIONCOUNT("Citation count"), MODIFICATIONDATE("modificationdate", FieldProperty.DATE); - public static final Set AUTOMATIC_FIELDS = Set.of(OWNER, TIMESTAMP, CREATIONDATE, MODIFICATIONDATE); private static final Map NAME_TO_STANDARD_FIELD = new HashMap<>(); 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 8a67b79ee9b..35eb20b0445 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -7,9 +7,9 @@ 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.logic.importer.fetcher.citation.semanticscholar.PaperDetails; import org.jabref.model.entry.BibEntry; import org.junit.jupiter.api.Nested; @@ -23,7 +23,7 @@ class SearchCitationsRelationsServiceTest { /** * Creates a mock CitationFetcher that returns specific results for citations and references */ - private CitationFetcher createMockFetcher(BibEntry targetEntry, List citationsToReturn, List referencesToReturn, Optional paperDetailsReturn) { + private CitationFetcher createMockFetcher(BibEntry targetEntry, List citationsToReturn, List referencesToReturn, Optional citationCount) { return CitationFetcherHelpersForTest.Mocks.from( entry -> { if (entry == targetEntry) { @@ -39,7 +39,7 @@ private CitationFetcher createMockFetcher(BibEntry targetEntry, List c }, entry -> { if (entry == targetEntry) { - return paperDetailsReturn != null ? paperDetailsReturn : Optional.empty(); + return citationCount != null ? citationCount : Optional.empty(); } return Optional.empty(); } @@ -227,7 +227,7 @@ void insertingAnEmptyReferencesShouldBePossible() { } @Test - void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse() { + void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse() throws FetcherException { int expectedResult = 0; BibEntry referencer = new BibEntry(); Map> referenceDatabase = new HashMap<>(); @@ -242,13 +242,12 @@ void serviceShouldUpdateCitationCountWithEmptyPaperDetailsResponse() { } @Test - void serviceShouldCorrectlyFetchCitationCountField() { + void serviceShouldCorrectlyFetchCitationCountField() throws FetcherException { int expectedResult = 3; BibEntry reference = new BibEntry(); - PaperDetails paperDetails = new PaperDetails(); - paperDetails.setCitationCount(3); + Integer citationCount = 3; Map> referencesDatabase = new HashMap<>(); - CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(paperDetails)); + CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(citationCount)); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( null, referencesDatabase, true @@ -260,15 +259,14 @@ void serviceShouldCorrectlyFetchCitationCountField() { } @Test - void serviceShouldUpdateBecauseIsisCitationsUpdatableTrue() { + void serviceShouldUpdateBecauseIsisCitationsUpdatableTrue() throws FetcherException { int expectedResult = 3; BibEntry reference = new BibEntry(); - PaperDetails paperDetails = new PaperDetails(); - paperDetails.setCitationCount(3); + Integer citationCount = 3; Map> referencesDatabase = new HashMap<>(); referencesDatabase.put(reference, List.of()); - CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(paperDetails)); + CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(citationCount)); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( null, referencesDatabase, true ); diff --git a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/CitationFetcherHelpersForTest.java b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/CitationFetcherHelpersForTest.java index 65d4b814165..3092048f1f0 100644 --- a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/CitationFetcherHelpersForTest.java +++ b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/CitationFetcherHelpersForTest.java @@ -5,7 +5,6 @@ import java.util.function.Function; import org.jabref.logic.importer.FetcherException; -import org.jabref.logic.importer.fetcher.citation.semanticscholar.PaperDetails; import org.jabref.model.entry.BibEntry; public class CitationFetcherHelpersForTest { @@ -13,7 +12,7 @@ public static class Mocks { public static CitationFetcher from( Function> retrieveCitedBy, Function> retrieveCiting, - Function> retrieveCitationCount + Function> retrieveCitationCount ) { return new CitationFetcher() { @Override @@ -27,7 +26,7 @@ public List searchCiting(BibEntry entry) { } @Override - public Optional searchCitationCount(BibEntry entry) throws FetcherException { + public Optional searchCitationCount(BibEntry entry) throws FetcherException { return retrieveCitationCount.apply(entry); } diff --git a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java index 4677d948182..34d93805cbe 100644 --- a/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java +++ b/jablib/src/test/java/org/jabref/logic/importer/fetcher/citation/semanticscholar/SemanticScholarCitationFetcherTest.java @@ -65,8 +65,8 @@ void smokeCitationCount() throws FetcherException { .withField(StandardField.ISSN, "0195-6663") .withField(StandardField.PUBLISHER, "Elsevier BV"); - Optional result = fetcher.searchCitationCount(entry); + Optional result = fetcher.searchCitationCount(entry); assertNotNull(result.get()); - assertThat(result.get().getCitationCount(), greaterThan(0)); + assertThat(result.get(), greaterThan(0)); } } From ba09528a47b3a50a584450a7a36499c4f8669ff3 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Mon, 14 Jul 2025 10:32:40 -0600 Subject: [PATCH 27/36] fix comments --- .../jabref/logic/citation/SearchCitationsRelationsService.java | 1 + 1 file changed, 1 insertion(+) 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 21d9faa0861..98288f7a1af 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -97,6 +97,7 @@ public int getCitationCount(BibEntry citationCounted, Optional actualFie } return citationCountResult.orElse(0); } + assert !actualFieldValue.isEmpty(); return Integer.parseInt(actualFieldValue.get()); } From 25e3649fbd9c310454e11e5742f16894c70be2e5 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Mon, 14 Jul 2025 10:37:09 -0600 Subject: [PATCH 28/36] fix comments --- .../jabref/logic/citation/SearchCitationsRelationsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 98288f7a1af..76721717196 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -85,7 +85,7 @@ public List searchCitations(BibEntry cited) { } public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue) throws FetcherException { - Optional citationCountResult = Optional.empty(); + Optional citationCountResult; boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) || actualFieldValue.isEmpty(); if (isFetchingAllowed) { From 4e0c1afdb4626f800dfe0d382df692d3d17c59b4 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Mon, 14 Jul 2025 10:56:50 -0600 Subject: [PATCH 29/36] fix comments --- .../jabref/gui/fieldeditors/CitationCountEditorViewModel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java index 4f71cf4f50e..4a464485845 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java @@ -59,7 +59,8 @@ public void getCitationCount(BibEntry bibEntry) { BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(bibEntry, fieldAux)) .onRunning(() -> fetchCitationCountInProgress.setValue(true)) .onFinished(() -> fetchCitationCountInProgress.setValue(false)) - .onFailure(e -> dialogService.showErrorDialogAndWait(Localization.lang("Error in getting Citation count"), e)) + .onFailure(e -> + dialogService.showErrorDialogAndWait(Localization.lang("Error Occurred"))) .onSuccess(identifier -> { entry.setField(field, String.valueOf(identifier)); }).executeWith(taskExecutor); From 1accb7c23255997a15ba649969536a0665f28bb7 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Mon, 14 Jul 2025 11:24:52 -0600 Subject: [PATCH 30/36] fix issues --- .../jabref/logic/citation/SearchCitationsRelationsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 76721717196..e7fd7be03f3 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -97,7 +97,7 @@ public int getCitationCount(BibEntry citationCounted, Optional actualFie } return citationCountResult.orElse(0); } - assert !actualFieldValue.isEmpty(); + assert actualFieldValue.isPresent(); return Integer.parseInt(actualFieldValue.get()); } From 41deb2b28b8fad7b9a46e9b663d413caed495f52 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Tue, 15 Jul 2025 13:00:20 -0600 Subject: [PATCH 31/36] fix comments --- .../org/jabref/gui/fieldeditors/CitationCountEditor.java | 4 +--- .../gui/fieldeditors/CitationCountEditorViewModel.java | 4 ++-- .../semanticscholar/SemanticScholarCitationFetcher.java | 2 +- .../citation/SearchCitationsRelationsServiceTest.java | 9 +++++---- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java index 6858ea10436..e76475f2841 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java @@ -38,7 +38,6 @@ public class CitationCountEditor extends HBox implements FieldEditorFX { @Inject private StateManager stateManager; @Inject private SearchCitationsRelationsService searchCitationsRelationsService; - private Optional entry = Optional.empty(); public CitationCountEditor(Field field, SuggestionProvider suggestionProvider, FieldCheckers fieldCheckers) { @@ -68,7 +67,7 @@ public CitationCountEditor(Field field, @FXML private void fetchCitationCount() { - this.entry.ifPresent(viewModel::getCitationCount); + viewModel.getCitationCount(); } public CitationCountEditorViewModel getViewModel() { @@ -77,7 +76,6 @@ public CitationCountEditorViewModel getViewModel() { @Override public void bindToEntry(BibEntry entry) { - this.entry = Optional.of(entry); viewModel.bindToEntry(entry); } diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java index 4a464485845..887c603cbc7 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java @@ -54,9 +54,9 @@ public boolean getFetchCitationCountInProgress() { return fetchCitationCountInProgress.get(); } - public void getCitationCount(BibEntry bibEntry) { + public void getCitationCount() { Optional fieldAux = entry.getField(field); - BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(bibEntry, fieldAux)) + BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(this.entry, fieldAux)) .onRunning(() -> fetchCitationCountInProgress.setValue(true)) .onFinished(() -> fetchCitationCountInProgress.setValue(false)) .onFailure(e -> 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 475b1d8975d..120da2360ee 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 @@ -37,7 +37,7 @@ public String getAPIUrl(String entry_point, BibEntry entry) { public String getUrlForCitationCount(BibEntry entry) { return SEMANTIC_SCHOLAR_API + "paper/" + "DOI:" + entry.getDOI().orElseThrow().asString() + "?fields=" + "citationCount" - + "&limit=1000"; + + "&limit=1"; } @Override 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 35eb20b0445..5c8360b2024 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -12,6 +12,7 @@ import org.jabref.logic.importer.fetcher.citation.CitationFetcherHelpersForTest; import org.jabref.model.entry.BibEntry; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -23,7 +24,7 @@ class SearchCitationsRelationsServiceTest { /** * Creates a mock CitationFetcher that returns specific results for citations and references */ - private CitationFetcher createMockFetcher(BibEntry targetEntry, List citationsToReturn, List referencesToReturn, Optional citationCount) { + private CitationFetcher createMockFetcher(BibEntry targetEntry, List citationsToReturn, List referencesToReturn, @NotNull Integer citationCount) { return CitationFetcherHelpersForTest.Mocks.from( entry -> { if (entry == targetEntry) { @@ -39,7 +40,7 @@ private CitationFetcher createMockFetcher(BibEntry targetEntry, List c }, entry -> { if (entry == targetEntry) { - return citationCount != null ? citationCount : Optional.empty(); + return Optional.of(citationCount); } return Optional.empty(); } @@ -247,7 +248,7 @@ void serviceShouldCorrectlyFetchCitationCountField() throws FetcherException { BibEntry reference = new BibEntry(); Integer citationCount = 3; Map> referencesDatabase = new HashMap<>(); - CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(citationCount)); + CitationFetcher fetcher = createMockFetcher(reference, null, null, citationCount); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( null, referencesDatabase, true @@ -266,7 +267,7 @@ void serviceShouldUpdateBecauseIsisCitationsUpdatableTrue() throws FetcherExcept Map> referencesDatabase = new HashMap<>(); referencesDatabase.put(reference, List.of()); - CitationFetcher fetcher = createMockFetcher(reference, null, null, Optional.of(citationCount)); + CitationFetcher fetcher = createMockFetcher(reference, null, null, citationCount); BibEntryCitationsAndReferencesRepository repository = BibEntryRelationsRepositoryTestHelpers.Mocks.from( null, referencesDatabase, true ); From fa1297f83f0e505968e3cb4b7bafb0dfe7b101a9 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Tue, 15 Jul 2025 13:08:41 -0600 Subject: [PATCH 32/36] remove unused import --- .../java/org/jabref/gui/fieldeditors/CitationCountEditor.java | 2 -- .../jabref/gui/fieldeditors/CitationCountEditorViewModel.java | 1 - 2 files changed, 3 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java index e76475f2841..68544e68f91 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java @@ -1,7 +1,5 @@ package org.jabref.gui.fieldeditors; -import java.util.Optional; - import javax.swing.undo.UndoManager; import javafx.fxml.FXML; diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java index 887c603cbc7..9eece17c3b7 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java @@ -16,7 +16,6 @@ import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.BackgroundTask; import org.jabref.logic.util.TaskExecutor; -import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.Field; public class CitationCountEditorViewModel extends AbstractEditorViewModel { From 4f1250d3d9236d5425b2deabbef8a144c5a1db50 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Tue, 15 Jul 2025 20:16:46 -0600 Subject: [PATCH 33/36] fix comments --- CHANGELOG.md | 2 +- .../citation/SearchCitationsRelationsService.java | 12 +++--------- .../SemanticScholarCitationFetcher.java | 6 +++--- .../org/jabref/model/entry/field/FieldProperty.java | 1 + .../org/jabref/model/entry/field/StandardField.java | 2 +- .../SearchCitationsRelationsServiceTest.java | 3 +-- 6 files changed, 10 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b719248aff..e8e21da7a06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv ### Added -- We added a field for fhe citation count field on the General tab. [#13477](https://github.com/JabRef/jabref/issues/13477) +- We added a field for the citation count field on the General tab. [#13477](https://github.com/JabRef/jabref/issues/13477) - We added focus on the field Link in the "Add file link" dialog. [#13486](https://github.com/JabRef/jabref/issues/13486) - We introduced a settings parameter to manage citations' relations local storage time-to-live with a default value set to 30 days. [#11189](https://github.com/JabRef/jabref/issues/11189) - We distribute arm64 images for Linux. [#10842](https://github.com/JabRef/jabref/issues/10842) 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 e7fd7be03f3..fb80968bebc 100644 --- a/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java +++ b/jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java @@ -85,16 +85,10 @@ public List searchCitations(BibEntry cited) { } public int getCitationCount(BibEntry citationCounted, Optional actualFieldValue) throws FetcherException { - Optional citationCountResult; - boolean isFetchingAllowed = relationsRepository.isCitationsUpdatable(citationCounted) - || actualFieldValue.isEmpty(); + boolean isFetchingAllowed = actualFieldValue.isEmpty() || + relationsRepository.isCitationsUpdatable(citationCounted); if (isFetchingAllowed) { - try { - citationCountResult = citationFetcher.searchCitationCount(citationCounted); - } catch (FetcherException e) { - LOGGER.error("Error while fetching citation count for entry", e); - throw e; - } + Optional citationCountResult = citationFetcher.searchCitationCount(citationCounted); return citationCountResult.orElse(0); } assert actualFieldValue.isPresent(); 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 120da2360ee..fe9ac59d3e7 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 @@ -104,12 +104,12 @@ public Optional searchCitationCount(BibEntry entry) throws FetcherExcep } URLDownload urlDownload = new URLDownload(referencesUrl); importerPreferences.getApiKey(getName()).ifPresent(apiKey -> urlDownload.addHeader("x-api-key", apiKey)); - PaperDetails referencesResponse = GSON.fromJson(urlDownload.asString(), PaperDetails.class); + PaperDetails paperDetails = GSON.fromJson(urlDownload.asString(), PaperDetails.class); - if (referencesResponse == null) { + if (paperDetails == null) { return Optional.empty(); } - return Optional.of(referencesResponse.getCitationCount()); + return Optional.of(paperDetails.getCitationCount()); } @Override diff --git a/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java b/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java index ef008e17b06..7dad6ca1faf 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/FieldProperty.java @@ -35,5 +35,6 @@ public enum FieldProperty { // Field content should be treated as data VERBATIM, + YES_NO } diff --git a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java index 0c4c071a6a3..e4a62490a00 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -136,9 +136,9 @@ public enum StandardField implements Field { // JabRef-specific fields GROUPS("groups"), OWNER("owner"), + CITATIONCOUNT("Citation count"), TIMESTAMP("timestamp", FieldProperty.DATE), CREATIONDATE("creationdate", FieldProperty.DATE), - CITATIONCOUNT("Citation count"), MODIFICATIONDATE("modificationdate", FieldProperty.DATE); public static final Set AUTOMATIC_FIELDS = Set.of(OWNER, TIMESTAMP, CREATIONDATE, MODIFICATIONDATE); 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 5c8360b2024..41609987871 100644 --- a/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java +++ b/jablib/src/test/java/org/jabref/logic/citation/SearchCitationsRelationsServiceTest.java @@ -12,7 +12,6 @@ import org.jabref.logic.importer.fetcher.citation.CitationFetcherHelpersForTest; import org.jabref.model.entry.BibEntry; -import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -24,7 +23,7 @@ class SearchCitationsRelationsServiceTest { /** * Creates a mock CitationFetcher that returns specific results for citations and references */ - private CitationFetcher createMockFetcher(BibEntry targetEntry, List citationsToReturn, List referencesToReturn, @NotNull Integer citationCount) { + private CitationFetcher createMockFetcher(BibEntry targetEntry, List citationsToReturn, List referencesToReturn, Integer citationCount) { return CitationFetcherHelpersForTest.Mocks.from( entry -> { if (entry == targetEntry) { From 49d6d473b80744f23e651a6a20efb38e9f037c42 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Tue, 15 Jul 2025 21:12:22 -0600 Subject: [PATCH 34/36] fix test cases --- .../main/java/org/jabref/model/entry/field/StandardField.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java index e4a62490a00..0c4c071a6a3 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -136,9 +136,9 @@ public enum StandardField implements Field { // JabRef-specific fields GROUPS("groups"), OWNER("owner"), - CITATIONCOUNT("Citation count"), TIMESTAMP("timestamp", FieldProperty.DATE), CREATIONDATE("creationdate", FieldProperty.DATE), + CITATIONCOUNT("Citation count"), MODIFICATIONDATE("modificationdate", FieldProperty.DATE); public static final Set AUTOMATIC_FIELDS = Set.of(OWNER, TIMESTAMP, CREATIONDATE, MODIFICATIONDATE); From 0630f860f5c6495659a1b5d61eb5381ab58666a2 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Thu, 17 Jul 2025 09:13:39 -0600 Subject: [PATCH 35/36] fix comments --- .../CitationCountEditorViewModel.java | 15 +++++++++++---- .../gui/fieldeditors/CitationCountEditor.fxml | 2 +- .../fetcher/citation/CitationFetcher.java | 2 +- .../jabref/model/entry/field/StandardField.java | 2 +- .../src/main/resources/l10n/JabRef_en.properties | 1 + 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java index 9eece17c3b7..6e1909f5bf6 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditorViewModel.java @@ -18,7 +18,12 @@ import org.jabref.logic.util.TaskExecutor; import org.jabref.model.entry.field.Field; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class CitationCountEditorViewModel extends AbstractEditorViewModel { + private static final Logger LOGGER = LoggerFactory.getLogger(CitationCountEditorViewModel.class); + protected final BooleanProperty fetchCitationCountInProgress = new SimpleBooleanProperty(false); private final TaskExecutor taskExecutor; private final DialogService dialogService; @@ -54,12 +59,14 @@ public boolean getFetchCitationCountInProgress() { } public void getCitationCount() { - Optional fieldAux = entry.getField(field); - BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(this.entry, fieldAux)) + Optional fieldContent = entry.getField(field); + BackgroundTask.wrap(() -> searchCitationsRelationsService.getCitationCount(this.entry, fieldContent)) .onRunning(() -> fetchCitationCountInProgress.setValue(true)) .onFinished(() -> fetchCitationCountInProgress.setValue(false)) - .onFailure(e -> - dialogService.showErrorDialogAndWait(Localization.lang("Error Occurred"))) + .onFailure(e -> { + dialogService.notify(Localization.lang("Error occurred when getting citation count, please try again or check the identifier.")); + LOGGER.error("Error while fetching citation count", e); + }) .onSuccess(identifier -> { entry.setField(field, String.valueOf(identifier)); }).executeWith(taskExecutor); diff --git a/jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml b/jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml index 73e7f7e6940..89f7f29bffa 100644 --- a/jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml +++ b/jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml @@ -14,7 +14,7 @@ + visible="${!controller.viewModel.fetchCitationCountInProgress}"/> diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index 72f35294d0c..2f95ddc0594 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -46,7 +46,7 @@ enum SearchType { * Get the paper details that includes citation count field for a given {@link BibEntry}. * * @param entry entry to search citation count field - * @return returns a {@link PaperDetails}, that includes citation count field (may be empty) + * @return returns a {@link Integer} for citation count field (may be empty) */ Optional searchCitationCount(BibEntry entry) throws FetcherException; diff --git a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java index 0c4c071a6a3..e4a62490a00 100644 --- a/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java +++ b/jablib/src/main/java/org/jabref/model/entry/field/StandardField.java @@ -136,9 +136,9 @@ public enum StandardField implements Field { // JabRef-specific fields GROUPS("groups"), OWNER("owner"), + CITATIONCOUNT("Citation count"), TIMESTAMP("timestamp", FieldProperty.DATE), CREATIONDATE("creationdate", FieldProperty.DATE), - CITATIONCOUNT("Citation count"), MODIFICATIONDATE("modificationdate", FieldProperty.DATE); public static final Set AUTOMATIC_FIELDS = Set.of(OWNER, TIMESTAMP, CREATIONDATE, MODIFICATIONDATE); diff --git a/jablib/src/main/resources/l10n/JabRef_en.properties b/jablib/src/main/resources/l10n/JabRef_en.properties index 5b983088790..ee9148c8ce9 100644 --- a/jablib/src/main/resources/l10n/JabRef_en.properties +++ b/jablib/src/main/resources/l10n/JabRef_en.properties @@ -311,6 +311,7 @@ Entry\ table\ columns=Entry table columns Entry\ Title\ (Required\ to\ deliver\ recommendations.)=Entry Title (Required to deliver recommendations.) Error=Error Error\ occurred\ when\ parsing\ entry=Error occurred when parsing entry +Error\ occurred\ when\ getting\ citation\ count,\ please\ try\ again\ or\ check\ the\ identifier.=Error occurred when getting citation count, please try again or check the identifier. Error\ during\ persistence\ of\ crawling\ results.=Error during persistence of crawling results. '%0'\ exists.\ Overwrite\ file?='%0' exists. Overwrite file? Export=Export From 5bd1d5a27bc201f99bd0375a8f9a3a0f035a2e46 Mon Sep 17 00:00:00 2001 From: Salvador Romo Date: Thu, 17 Jul 2025 10:39:17 -0600 Subject: [PATCH 36/36] fix tests --- .../logic/importer/fetcher/citation/CitationFetcher.java | 1 - .../OldOpenOfficeCalcExportFormatContentSingleEntry.xml | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java index 2f95ddc0594..84d44c0199b 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationFetcher.java @@ -4,7 +4,6 @@ import java.util.Optional; import org.jabref.logic.importer.FetcherException; -import org.jabref.logic.importer.fetcher.citation.semanticscholar.PaperDetails; import org.jabref.model.entry.BibEntry; /** diff --git a/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml b/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml index f4ad981fbfd..acb7cf686dd 100644 --- a/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml +++ b/jablib/src/test/resources/org/jabref/logic/exporter/OldOpenOfficeCalcExportFormatContentSingleEntry.xml @@ -383,13 +383,13 @@ Owner - Timestamp + Citation count - Creationdate + Timestamp - Citation count + Creationdate Modificationdate