Skip to content

Fix reset and import for CitationKeyPreferences#15522

Merged
calixtus merged 14 commits into
mainfrom
citation-key-prefs
Apr 11, 2026
Merged

Fix reset and import for CitationKeyPreferences#15522
calixtus merged 14 commits into
mainfrom
citation-key-prefs

Conversation

@calixtus

@calixtus calixtus commented Apr 9, 2026

Copy link
Copy Markdown
Member

Related issues and pull requests

Follow-up to #15514

PR Description

See qodo comment and title

Steps to test

Run, open preferences, text reset and import

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

@calixtus calixtus added status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers dev: code-quality Issues related to code or architecture decisions component: citationkey-generator component: preferences labels Apr 9, 2026
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix CitationKeyPatternPreferences reset/import and remove reflection

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Remove reflection-based pattern discovery in CitationKeyPattern
• Fix reset and import functionality for CitationKeyPatternPreferences
• Refactor CitationKeyPatternPreferences to use default factory method
• Standardize preference key naming with CITATION_KEY_ prefix
• Remove unused defaultPattern parameter from preferences
Diagram
flowchart LR
  A["CitationKeyPattern<br/>Reflection-based"] -->|"Replace with<br/>static lists"| B["CitationKeyPattern<br/>Explicit categories"]
  C["CitationKeyPatternPreferences<br/>Constructor-based"] -->|"Add factory method"| D["CitationKeyPatternPreferences<br/>getDefault()"]
  E["Scattered preference keys"] -->|"Standardize naming"| F["CITATION_KEY_ prefixed keys"]
  G["CitationKeyPatternsPanel<br/>Injected preferences"] -->|"Remove dependency"| H["CitationKeyPatternsPanel<br/>Simplified initialization"]
Loading

Grey Divider

File Changes

1. jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPattern.java ✨ Enhancement +72/-78

Replace reflection with explicit static pattern lists

jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPattern.java


2. jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java 🐞 Bug fix +56/-53

Add default factory method and remove defaultPattern parameter

jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java


3. jabgui/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternsPanel.java 🐞 Bug fix +5/-9

Remove dependency injection and simplify initialization

jabgui/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternsPanel.java


View more (7)
4. jabgui/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternsPanelViewModel.java 🐞 Bug fix +3/-6

Remove preferences parameter and use static default access

jabgui/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternsPanelViewModel.java


5. jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java ✨ Enhancement +96/-97

Standardize citation key preference key names with prefix

jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java


6. jabkit/src/main/java/org/jabref/toolkit/commands/GenerateCitationKeys.java 🐞 Bug fix +3/-2

Update to use SimpleObjectProperty for keyword delimiter

jabkit/src/main/java/org/jabref/toolkit/commands/GenerateCitationKeys.java


7. jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGeneratorTestUtils.java 🧪 Tests +3/-2

Update test utility to use SimpleObjectProperty

jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGeneratorTestUtils.java


8. jablib/src/main/java/org/jabref/logic/citationkeypattern/GlobalCitationKeyPatterns.java ✨ Enhancement +3/-1

Add NonNull annotation to fromPattern method

jablib/src/main/java/org/jabref/logic/citationkeypattern/GlobalCitationKeyPatterns.java


9. jablib/src/main/java/org/jabref/logic/net/ssl/SSLPreferences.java Miscellaneous +0/-4

Remove unused truststorePathProperty accessor method

jablib/src/main/java/org/jabref/logic/net/ssl/SSLPreferences.java


10. jabgui/src/main/java/org/jabref/migrations/PreferencesMigrations.java 🐞 Bug fix +1/-1

Update to use standardized CITATION_KEY_DEFAULT_PATTERN key

jabgui/src/main/java/org/jabref/migrations/PreferencesMigrations.java


Grey Divider

Qodo Logo

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

qodo-free-for-open-source-projects Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1)   📘 Rule violations (1)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (1)
📘\ ⚙ Maintainability (1)

Grey Divider


Action required

1. Commented-out PROXY_PASSWORD constant 📘
Description
A code-like line is kept as a comment (// PROXY_PASSWORD = "proxyPassword" ...), which is
effectively commented-out code and adds clutter. This violates the requirement to remove
commented-out code in changed files.
Code

jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[338]

+    // PROXY_PASSWORD = "proxyPassword" handled by KeyRing
Evidence
PR Compliance ID 4 forbids leaving or adding commented-out code in changed files. The PR adds a
commented-out version of the removed PROXY_PASSWORD constant as a comment.

AGENTS.md
jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[338-338]

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 code adds a comment that is effectively commented-out code (`// PROXY_PASSWORD = "proxyPassword" ...`). Compliance requires removing commented-out code in changed files.
## Issue Context
The constant `PROXY_PASSWORD` was removed, but its assignment is still present as a code-like comment.
## Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[338-338]

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


2. Empty default citekey pattern🐞
Description
CitationKeyPatternPreferences.getDefault() initializes GlobalCitationKeyPatterns with an empty
default pattern, which becomes the fallback default pattern in JabRefCliPreferences and causes
generated citation keys (and UI resets) to become empty. This is a functional regression affecting
citation key generation when no explicit default pattern is stored in preferences (e.g., fresh
installs, after reset/clear).
Code

jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java[R55-67]

+    private CitationKeyPatternPreferences() {
+        this(
+                false,                                    // shouldTransliterateFieldsForCitationKey
+                false,                                    // shouldAvoidOverwriteCiteKey
+                true,                                     // shouldWarnBeforeOverwriteCiteKey
+                false,                                    // shouldGenerateCiteKeysBeforeSaving
+                KeySuffix.SECOND_WITH_A,
+                "",                                       // keyPatternRegex
+                "[auth][year]",                           // keyPatternReplacement
+                "-`ʹ:!;?^$",                              // unwantedCharacters
+                GlobalCitationKeyPatterns.fromPattern(""),
+                new SimpleObjectProperty<>(',') // keywordDelimiter
+        );
Evidence
CitationKeyPatternPreferences.getDefault() currently builds defaults with
GlobalCitationKeyPatterns.fromPattern(""), i.e., an empty global default pattern.
JabRefCliPreferences uses defaults.getKeyPatterns().getDefaultValue().stringRepresentation() as
the fallback when reading CITATION_KEY_DEFAULT_PATTERN, so the empty default propagates into
runtime preferences. MetaData then builds citation key patterns starting from these global patterns,
and CitationKeyGenerator expands the selected pattern; if it is empty, generated keys become empty
strings.

jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java[55-67]
jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1425-1492]
jablib/src/main/java/org/jabref/model/metadata/MetaData.java[128-136]
jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java[198-206]
jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGeneratorTestUtils.java[9-21]

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

## Issue description
`CitationKeyPatternPreferences.getDefault()` currently sets the global key pattern default to the empty string, which causes fallback preference loading and “reset” behavior to use an empty citation key pattern.
### Issue Context
This default flows into `JabRefCliPreferences#getGlobalCitationKeyPattern(...)` as the fallback for `CITATION_KEY_DEFAULT_PATTERN`, and then into `MetaData#getCiteKeyPatterns(...)` and `CitationKeyGenerator`.
### Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java[55-67]
- jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1489-1492]
### Implementation notes
- Update `CitationKeyPatternPreferences.getDefault()` to use the intended application default global pattern (very likely `"[auth][year]"`) via `GlobalCitationKeyPatterns.fromPattern("[auth][year]")`.
- Ensure `keyPatternReplacement` default is consistent with expected defaults (tests commonly use empty replacement unless regex is set).
- Consider adding/adjusting a small unit test asserting the default global pattern is non-empty and equals the intended default.

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


3. --pattern flag ignored 🐞
Description
GenerateCitationKeys defines the CLI option --pattern but no longer applies it when building
CitationKeyPatternPreferences, so the flag has no effect. Users cannot override the default citation
key pattern via CLI anymore.
Code

jabkit/src/main/java/org/jabref/toolkit/commands/GenerateCitationKeys.java[R132-136]

        keyPatternReplacement != null ? keyPatternReplacement : existingPreferences.getKeyPatternReplacement(),
        unwantedCharacters != null ? unwantedCharacters : existingPreferences.getUnwantedCharacters(),
        getKeyPatterns(keyPatterns, existingPreferences.getKeyPatterns()),
-                pattern != null ? pattern : existingPreferences.getDefaultPattern(),
-                keywordDelimiter != null ? keywordDelimiter : existingPreferences.getKeywordDelimiter()
+                new SimpleObjectProperty<>(keywordDelimiter != null ? keywordDelimiter : existingPreferences.getKeywordDelimiter())
);
Evidence
The command declares @Option(names = "--pattern") private String pattern; but
getCitationKeyGenerator() constructs CitationKeyPatternPreferences without referencing
pattern. The helper getKeyPatterns(...) only overlays per-entry-type patterns and otherwise
copies the existing default, so there is no place where the --pattern override is applied.

jabkit/src/main/java/org/jabref/toolkit/commands/GenerateCitationKeys.java[49-51]
jabkit/src/main/java/org/jabref/toolkit/commands/GenerateCitationKeys.java[122-158]

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 `--pattern` CLI option is currently ignored, so `jabkit citationkeys generate --pattern ...` cannot override the global/default citation key pattern.
### Issue Context
The code still defines the `pattern` option but does not use it when constructing the `CitationKeyPatternPreferences` / `GlobalCitationKeyPatterns` used by `CitationKeyGenerator`.
### Fix Focus Areas
- jabkit/src/main/java/org/jabref/toolkit/commands/GenerateCitationKeys.java[49-51]
- jabkit/src/main/java/org/jabref/toolkit/commands/GenerateCitationKeys.java[122-158]
### Implementation notes
- Thread `pattern` into `getKeyPatterns(...)` (e.g., `getKeyPatterns(pattern, keyPatterns, existingPreferences.getKeyPatterns())`).
- If `pattern != null`, set the returned `GlobalCitationKeyPatterns` default value to `new CitationKeyPattern(pattern)` (or `GlobalCitationKeyPatterns.fromPattern(pattern)` and then overlay per-type patterns).
- Add a small CLI/unit test verifying `--pattern` changes the generated keys.

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



Remediation recommended

4. Reset creates persistent override🐞
Description
CitationKeyPatternsPanelViewModel.setItemToDefaultPattern sets a concrete pattern string on reset,
which is then stored as an explicit per-entry-type override instead of clearing the override to
inherit the global default. This can lock an entry type to an old pattern even after the user
changes the "Default pattern" row later.
Code

jabgui/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternsPanelViewModel.java[R69-76]

public void setItemToDefaultPattern(CitationKeyPatternsPanelItemModel item) {
-        item.setPattern(keyPatternPreferences.getDefaultPattern());
+        item.setPattern(CitationKeyPatternPreferences.getDefault().getKeyPatterns().getDefaultValue().stringRepresentation());
}
public void resetAll() {
patternListProperty.forEach(item -> item.setPattern(""));
-        defaultItemProperty.getValue().setPattern(keyPatternPreferences.getDefaultPattern());
+        defaultItemProperty.getValue().setPattern(CitationKeyPatternPreferences.getDefault().getKeyPatterns().getDefaultValue().stringRepresentation());
}
Evidence
The per-row reset sets item.setPattern(...) to a concrete default pattern string. In the
preferences tab save path, non-default entry types are only added as overrides when their pattern
string is non-empty; therefore, reset creates/keeps an explicit override rather than removing it
(empty string) to inherit the default pattern row.

jabgui/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternsPanelViewModel.java[69-76]
jabgui/src/main/java/org/jabref/gui/preferences/citationkeypattern/CitationKeyPatternTabViewModel.java[84-93]

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

## Issue description
Row-level reset should remove the entry-type override (set pattern to empty) so the entry type inherits the current "Default pattern". Current implementation sets a concrete pattern string, which gets stored as a persistent override.
### Issue Context
`CitationKeyPatternTabViewModel.storeSettings()` persists type-specific patterns only when the row pattern is non-empty.
### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternsPanelViewModel.java[69-76]
- jabgui/src/main/java/org/jabref/gui/preferences/citationkeypattern/CitationKeyPatternTabViewModel.java[84-93]
### Implementation notes
- In `setItemToDefaultPattern(item)`: if `item.getEntryType().getName().equals("default")`, reset to the application default pattern string; otherwise set `item.setPattern("")` to clear the override.
- Keep `resetAll()` behavior consistent: clear all per-type overrides and reset the default-row pattern to the application default.

ⓘ 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

@calixtus calixtus enabled auto-merge April 10, 2026 11:43
keyPattern,
"",
',');
new SimpleObjectProperty<>(','));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks idd, why does this need a new Property in the constructor? We don't use that anywhere else

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had a longer chat in devchannel. Summary:

KeyDelemitier property incorporates a foreign preference from No entry preferences to keep CitationKeyPreferences self-contained and not having to refactor everything to also accept BibEntryPreferences.
Hacky solution has been partially inherited from before, but is now dynamically adapting to a changing base preference.

@Siedlerchr

Copy link
Copy Markdown
Member

What about the last qodo issue?

GenerateCitationKeys defines the CLI option --pattern but no longer applies it when building
CitationKeyPatternPreferences, so the flag has no effect. Users cannot override the default citation
key pattern via CLI anymore.
is that valid?

@calixtus

Copy link
Copy Markdown
Member Author

What about the last qodo issue?

GenerateCitationKeys defines the CLI option --pattern but no longer applies it when building
CitationKeyPatternPreferences, so the flag has no effect. Users cannot override the default citation
key pattern via CLI anymore.
is that valid?

I commented on it. Its addressed in the helper method

Comment on lines +206 to +208
if (this.keywordDelimiter.isBound()) {
this.keywordDelimiter.unbind();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bind() calls unbind() internally, so this block is unnecessary.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will resolve in next prefs pr

@calixtus calixtus added this pull request to the merge queue Apr 11, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Apr 11, 2026
Merged via the queue into main with commit 2591c7f Apr 11, 2026
65 checks passed
@calixtus calixtus deleted the citation-key-prefs branch April 11, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: citationkey-generator component: preferences dev: code-quality Issues related to code or architecture decisions status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers 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.

3 participants