Skip to content

Feature/citation count dropdown#15216

Merged
Siedlerchr merged 14 commits into
JabRef:mainfrom
aliyasirnac:feature/citation-count-dropdown
Mar 6, 2026
Merged

Feature/citation count dropdown#15216
Siedlerchr merged 14 commits into
JabRef:mainfrom
aliyasirnac:feature/citation-count-dropdown

Conversation

@aliyasirnac

@aliyasirnac aliyasirnac commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Related issues and pull requests

Closes #15134

PR Description

This PR adds a fetcher selection dropdown to the CitationCountEditor in the General tab, allowing users to choose which source (Semantic Scholar, OpenAlex, OpenCitations, or scite.ai) is used to fetch the citation count for an entry. A new CitationCountFetcherType enum was introduced to separate citation count fetching from citation relation fetching, and SciteAiFetcher was updated to implement CitationCountFetcher. The selected fetcher is stored as a preference and kept in sync with SearchCitationsRelationsService.

PR screenshot

Ekran Resmi 2026-03-03 18 44 10

Steps to test

  1. Open JabRef and add an entry with a DOI (e.g. 10.1145/1028174.971312)
  2. Navigate to the General tab in the entry editor
  3. Find the Citationcount field — a dropdown should appear next to it
  4. Select a different fetcher from the dropdown (Semantic Scholar, OpenAlex, etc.)
  5. Click the refresh button — citation count should update from the selected source

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • [/] I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@github-actions

Copy link
Copy Markdown
Contributor

Hey @aliyasirnac! 👋

Thank you for contributing to JabRef!

We have automated checks in place, based on which you will soon get feedback if any of them are failing. We also use Qodo for review assistance. It will update your pull request description with a review help and offer suggestions to improve the pull request.

After all automated checks pass, a maintainer will also review your contribution. Once that happens, you can go through their comments in the "Files changed" tab and act on them, or reply to the conversation if you have further inputs. You can read about the whole pull request process in our contribution guide.

Please ensure that your pull request is in line with our AI Usage Policy and make necessary disclosures.

@github-actions github-actions Bot added first contrib good first issue An issue intended for project-newcomers. Varies in difficulty. labels Feb 26, 2026
@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Feb 26, 2026
@testlens-app

This comment has been minimized.

@aliyasirnac aliyasirnac marked this pull request as ready for review March 3, 2026 15:51
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add citation count fetcher selection dropdown in entry editor

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add citation count fetcher selection dropdown to entry editor
• Support multiple citation sources: Semantic Scholar, OpenAlex, OpenCitations, scite.ai
• Implement CitationCountFetcherType enum for citation count fetching
• Integrate SciteAiFetcher as CitationCountFetcher implementation
• Persist user's fetcher selection as preference
Diagram
flowchart LR
  A["CitationCountEditor UI"] -->|displays| B["Fetcher ComboBox"]
  B -->|selects| C["CitationCountFetcherType"]
  C -->|creates| D["CitationCountFetcher"]
  D -->|fetches from| E["Multiple Sources"]
  E -->|includes| F["Semantic Scholar"]
  E -->|includes| G["OpenAlex"]
  E -->|includes| H["OpenCitations"]
  E -->|includes| I["scite.ai"]
  C -->|stored in| J["EntryEditorPreferences"]
  J -->|synced with| K["SearchCitationsRelationsService"]
Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java ✨ Enhancement +17/-0

Add fetcher selection dropdown to citation count editor

jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java


2. jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorPreferences.java ✨ Enhancement +18/-0

Add citation count fetcher type preference property

jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorPreferences.java


3. jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml ✨ Enhancement +2/-0

Add ComboBox control to citation count editor layout

jabgui/src/main/resources/org/jabref/gui/fieldeditors/CitationCountEditor.fxml


View more (7)
4. jabgui/src/main/java/org/jabref/gui/JabRefGUI.java ✨ Enhancement +1/-0

Pass citation count fetcher type to search service

jabgui/src/main/java/org/jabref/gui/JabRefGUI.java


5. jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java ✨ Enhancement +2/-0

Initialize citation count fetcher preference from backing store

jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java


6. jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationCountFetcherType.java ✨ Enhancement +43/-0

Create enum for citation count fetcher type selection

jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationCountFetcherType.java


7. jablib/src/main/java/org/jabref/logic/importer/fetcher/SciteAiFetcher.java ✨ Enhancement +16/-1

Implement CitationCountFetcher interface in SciteAiFetcher

jablib/src/main/java/org/jabref/logic/importer/fetcher/SciteAiFetcher.java


8. jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java ✨ Enhancement +16/-1

Integrate citation count fetcher with listener support

jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java


9. jablib/src/test/java/org/jabref/logic/importer/fetcher/SciteAiFetcherTest.java 🧪 Tests +31/-0

Add tests for SciteAiFetcher citation count functionality

jablib/src/test/java/org/jabref/logic/importer/fetcher/SciteAiFetcherTest.java


10. CHANGELOG.md 📝 Documentation +1/-1

Document citation count fetcher selection feature

CHANGELOG.md


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (3) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Test uses setField📘 Rule violation ✓ Correctness
Description
The new test constructs a BibEntry using setField, which conflicts with the project convention
to use withField withers for BibEntry construction/modification. This reduces consistency and can
encourage mutable patterns in tests.
Code

jablib/src/test/java/org/jabref/logic/importer/fetcher/SciteAiFetcherTest.java[R60-62]

+        BibEntry entry = new BibEntry();
+        entry.setField(StandardField.DOI, "10.1145/1028174.971312");
+
Evidence
PR Compliance ID 32 explicitly requires using BibEntry withers (withField) instead of setField
in tests/construction; the added test uses entry.setField(...).

AGENTS.md
jablib/src/test/java/org/jabref/logic/importer/fetcher/SciteAiFetcherTest.java[60-62]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new test uses `BibEntry#setField(...)` instead of the preferred `BibEntry#withField(...)` pattern.
## Issue Context
Project test/construction conventions prefer withers to keep object construction fluent and consistent.
## Fix Focus Areas
- jablib/src/test/java/org/jabref/logic/importer/fetcher/SciteAiFetcherTest.java[58-67]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Selection not persisted🐞 Bug ✓ Correctness
Description
The citation-count fetcher dropdown is bound to a preferences property, but JabRefGuiPreferences
always loads SEMANTIC_SCHOLAR and never stores updates, so the user’s selection will be lost after
restart.
Code

jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[R413-419]

        getBoolean(AUTOLINK_FILES_ENABLED, defaults.autoLinkFilesEnabled()),
        EntryEditorPreferences.JournalPopupEnabled.fromString(get(JOURNAL_POPUP, defaults.shouldEnableJournalPopup().name())),
        CitationFetcherType.SEMANTIC_SCHOLAR, // always use default
+                CitationCountFetcherType.SEMANTIC_SCHOLAR, // always use default
        getBoolean(SHOW_SCITE_TAB, defaults.shouldShowSciteTab()),
        getBoolean(SHOW_USER_COMMENTS_FIELDS, defaults.shouldShowUserCommentsFields()),
        getDouble(ENTRY_EDITOR_PREVIEW_DIVIDER_POS, defaults.getPreviewWidthDividerPosition())
Evidence
The UI writes the selected fetcher into EntryEditorPreferences via a bidirectional binding, but
JabRefGuiPreferences (the backing store bridge) neither listens to citationCountFetcherType changes
nor reads it from preferences; instead, it hard-codes the default every time preferences are loaded.

jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java[72-80]
jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[382-398]
jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[401-420]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The selected citation-count fetcher is bound to `EntryEditorPreferences.citationCountFetcherTypeProperty()`, but it is never written to (or read from) the preferences backing store. This means the selection resets to the default after restart.
### Issue Context
`JabRefGuiPreferences` already persists many `EntryEditorPreferences` fields via `EasyBind.listen(...)`, and reconstructs `EntryEditorPreferences` in `getEntryEditorPreferencesFromBackingStore(...)`. The new `citationCountFetcherType` needs to be handled there as well.
### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[375-420]
- jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java[72-80]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Hard-coded ComboBox width 📘 Rule violation ⛯ Reliability
Description
The new UI code hard-codes fetcherComboBox width to 160px, which can cause truncation/overlap or
poor scaling on different font sizes and translations. This violates the requirement to avoid
brittle hard-coded layout constraints in UI code.
Code

jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java[R72-74]

+        fetcherComboBox.setItems(FXCollections.observableList(List.of(CitationCountFetcherType.values())));
+        fetcherComboBox.setTooltip(new Tooltip(Localization.lang("Select citation fetcher")));
+        fetcherComboBox.setPrefWidth(160);
Evidence
PR Compliance ID 42 requires avoiding brittle hard-coded layout constraints; the added code sets a
fixed pixel width for the new dropdown.

jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java[72-80]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new `fetcherComboBox` dropdown uses a hard-coded pixel width (`setPrefWidth(160)`), which is a brittle layout constraint and may break with longer localized strings, different fonts, or window sizes.
## Issue Context
Compliance requires UI layout to be responsive and avoid hard-coded sizing constraints.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/CitationCountEditor.java[72-80]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Test uses Optional.get() 📘 Rule violation ⛯ Reliability
Description
The new test asserts presence and then accesses the value via Optional.get(), which is an unsafe
Optional access pattern discouraged by the checklist. It also relies on boolean-condition assertions
rather than directly asserting the extracted value after a safe unwrap.
Code

jablib/src/test/java/org/jabref/logic/importer/fetcher/SciteAiFetcherTest.java[R63-66]

+        Optional<Integer> result = fetcher.getCitationCount(entry);
+
+        assertTrue(result.isPresent());
+        assertTrue(result.get() > 0);
Evidence
PR Compliance ID 39 requires avoiding unsafe Optional access (including Optional.get()), and PR
Compliance ID 30 prefers asserting object contents/values over boolean conditions where possible;
the added test uses both result.get() and assertTrue(result.get() > 0).

AGENTS.md
jablib/src/test/java/org/jabref/logic/importer/fetcher/SciteAiFetcherTest.java[63-67]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new test uses `Optional.get()` and boolean-condition assertions, which is discouraged by the compliance rules for safe Optional handling and clearer assertions.
## Issue Context
Tests should avoid unsafe Optional access patterns and prefer assertions on extracted values when feasible.
## Fix Focus Areas
- jablib/src/test/java/org/jabref/logic/importer/fetcher/SciteAiFetcherTest.java[63-67]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Null-safety missing 🐞 Bug ⛯ Reliability
Description
CitationCountFetcherType is switched on without null checks, and SearchCitationsRelationsService
passes the property value directly; if the property becomes null, citation count fetching can throw
an NPE.
Code

jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java[R55-57]

+        this.citationCountFetcher = CitationCountFetcherType.getCitationCountFetcher(
+                citationCountFetcherTypeProperty.get(),
+                importerPreferences);
Evidence
SearchCitationsRelationsService uses citationCountFetcherTypeProperty.get()/newValue directly to
build a fetcher, while CitationCountFetcherType.getCitationCountFetcher performs switch (type)
without guarding against null. EntryEditorPreferences exposes a public setter without null
validation, so null can be introduced by callers or future preference parsing changes.

jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java[55-73]
jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationCountFetcherType.java[30-42]
jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorPreferences.java[337-347]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`CitationCountFetcherType.getCitationCountFetcher` uses `switch(type)` without null handling, and `SearchCitationsRelationsService` forwards potentially-null values from an `ObjectProperty`. If the property is ever set to null, citation count fetching can crash with NPE.
### Issue Context
Even if the UI usually provides a value, null can be introduced by code (public setter) or by future preference parsing / migration logic.
### Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/importer/fetcher/citation/CitationCountFetcherType.java[30-42]
- jablib/src/main/java/org/jabref/logic/citation/SearchCitationsRelationsService.java[55-73]
- jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorPreferences.java[337-347]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@testlens-app

This comment has been minimized.

@testlens-app

This comment has been minimized.

@testlens-app

This comment has been minimized.

@testlens-app

This comment has been minimized.

@testlens-app

This comment has been minimized.

@testlens-app

This comment has been minimized.

@testlens-app

This comment has been minimized.

@aliyasirnac

This comment was marked as outdated.

@testlens-app

This comment has been minimized.

@testlens-app

testlens-app Bot commented Mar 6, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 856595a
▶️ Tests: 10126 executed
⚪️ Checks: 52/52 completed


Learn more about TestLens at testlens.app.

@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Mar 6, 2026
@Siedlerchr Siedlerchr added this pull request to the merge queue Mar 6, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Mar 6, 2026
Merged via the queue into JabRef:main with commit 063e60e Mar 6, 2026
52 checks passed
@aliyasirnac aliyasirnac deleted the feature/citation-count-dropdown branch March 6, 2026 14:27
Siedlerchr added a commit to statxc/jabref that referenced this pull request Mar 10, 2026
* upstream/main: (59 commits)
  Fix 15000 identifier (JabRef#15286)
  Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (JabRef#15305)
  Supress JavaFX VirtualFlow Info log noise for large libraries (10k+). (JabRef#15298)
  Chore(deps): Bump commons-logging:commons-logging in /versions (JabRef#15304)
  Fix merge dialog closing immediately when only one PDF importer returns metadata (JabRef#15127) (JabRef#15287)
  Fixed nullable eventhandlers (JabRef#15288)
  New Crowdin updates (JabRef#15285)
  Fix the ESC key for GlobalSearchResultDialog (JabRef#15259)
  Remove jbang plugin banner (JabRef#15282)
  Chore(deps): Bump org.apache.httpcomponents.core5:httpcore5 in /versions (JabRef#15281)
  Udpate to latest gradle master (JabRef#15279)
  Migrate to GemsFX Notifications (JabRef#14762)
  Chore(deps): Bump JetBrains/junie-github-action from 0 to 1 (JabRef#15272)
  Chore(deps): Bump docker/setup-qemu-action from 3 to 4 (JabRef#15269)
  Feature/citation count dropdown (JabRef#15216)
  Update dependency org.apache.maven.plugins:maven-resources-plugin to v3.5.0 (JabRef#15275)
  Chore(deps): Bump jablib/src/main/resources/csl-styles (JabRef#15273)
  Fix more security
  Fix pr_body leakage
  Chore: add dependency-management.md (JabRef#15278)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

first contrib good first issue An issue intended for project-newcomers. Varies in difficulty. status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add citation count selection to entry editor

3 participants